用Vue3-video-play写一个播放组件
时间: 2023-05-27 11:07:47 浏览: 43
以下是一个简单的Vue3视频播放组件:
```
<template>
<div class="video-player">
<video ref="video" :src="src" @play="onPlay" @pause="onPause"></video>
<div class="controls">
<button @click="togglePlay">
{{ isPlaying ? '暂停' : '播放' }}
</button>
<span>{{ currentTime }}</span>
<input type="range" min="0" :max="duration" :value="currentTime" @input="onSeek">
<span>{{ duration }}</span>
</div>
</div>
</template>
<script>
import { ref, watch } from 'vue'
export default {
name: 'VideoPlayer',
props: {
src: {
type: String,
required: true
}
},
setup(props) {
const videoEl = ref(null)
const isPlaying = ref(false)
const currentTime = ref('00:00')
const duration = ref('00:00')
const togglePlay = () => {
if (isPlaying.value) {
videoEl.value.pause()
} else {
videoEl.value.play()
}
}
const onPlay = () => {
isPlaying.value = true
}
const onPause = () => {
isPlaying.value = false
}
const onSeek = event => {
videoEl.value.currentTime = event.target.value
}
const updateTime = () => {
const time = videoEl.value.currentTime
const minutes = Math.floor(time / 60)
const seconds = Math.floor(time % 60)
currentTime.value = `${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
}
watch(isPlaying, value => {
if (value) {
videoEl.value.addEventListener('timeupdate', updateTime)
} else {
videoEl.value.removeEventListener('timeupdate', updateTime)
}
})
watch(videoEl, value => {
if (value) {
value.addEventListener('durationchange', () => {
const time = value.duration
const minutes = Math.floor(time / 60)
const seconds = Math.floor(time % 60)
duration.value = `${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
})
}
})
return {
videoEl,
isPlaying,
currentTime,
duration,
togglePlay,
onPlay,
onPause,
onSeek,
updateTime
}
}
}
</script>
<style>
.video-player {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
}
.video-player video {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
.video-player .controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
color: white;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
}
.video-player .controls button {
background-color: transparent;
border: none;
color: white;
font-size: 16px;
cursor: pointer;
}
.video-player .controls input[type="range"] {
width: 100%;
margin: 0 10px;
}
.video-player .controls span {
font-size: 14px;
}
</style>
```
该组件依赖`vue`,通过`props`传入视频的`src`,然后使用`ref`引用`video`元素,通过`watch`监听`isPlaying`的变化,更新视频的当前时间,使用`addEventListener`和`removeEventListener`在播放和暂停时更新当前时间。还使用了`setup`函数来定义组件的逻辑,`return`返回需要暴露出去的属性和函数。组件的样式使用了相对定位和padding-bottom来实现16:9的响应式比例。
相关推荐
![vue](https://img-home.csdnimg.cn/images/20210720083646.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)