|
介绍
vue3Douyin 是一款基于vite2构建工具搭建开发的vue3仿制抖音实战项目。使用了vue3.0+vuex+vant3+v3popup等技术编码开发,实现小视频上下滑动切换、点赞/评论/分享等功能。
小视频页有附近/关注/推荐三大模块,可以实现左右及上下滑动切换效果。
如上图:这个是原型设计,最终效果是下面这些展示图片。
实现技术
- 构建工具:Vite.js
- 编辑器:Vscode
- MVVM框架:Vue^3.0.5
- 状态管理:Vuex^4.0.0-rc.2
- 页面路由:Vue-Router^4.0.3
- UI组件库:Vant^3.0.4 (有赞手机端vue3组件库)
- 弹框组件:v3popup(基于vue3自定义手机端弹出层组件)
- 字体图标:阿里iconfont图标
- 顶部条+底部栏:基于vue3自定义navbar/tabbar组件
项目结构目录
vue3实现短视频/直播效果
小视频/直播模板整体布局分为顶部Navbar、视频信息区、底部Toolbar三个模块。
- <template>
- <div class="bg-161823">
- <!-- >>顶部NavBar -->
- <navbar :back="false" bgcolor="transparent" transparent>
- <template v-slot:title>
- ...
- </template>
- <template v-slot:right><div><i class="iconfont icon-search"></i></div></template>
- </navbar>
- <!-- >>主面板 -->
- <div class="vui__scrollview flex1">
- <div class="vui__swipeview">
- <!-- ///滑动切换区 -->
- <van-swipe ref="swipeHorizontalRef" :show-indicators="false" :loop="false" @change="handleSwipeHorizontal">
- <van-swipe-item v-for="(item,index) in videoLs" :key="index">
- <template v-if="item.category == 'nearby'">
- <div class="swipe__nearLs">
- ...
- </div>
- </template>
- <template v-if="item.category == 'recommend' || item.category == 'follow'">
- <van-swipe vertical lazy-render :show-indicators="false" :loop="false" @change="handleSwipeVertical">
- <van-swipe-item v-for="(item2, index2) in item.list" :key="index2">
- <!-- ///视频模块 -->
- <div class="swipe__video">
- <video class="vdplayer" :id="'vd-'+index+'-'+index2" loop preload="auto"
- :src="item2.src"
- :poster="item2.poster"
- webkit-playsinline="true"
- x5-video-player-type="h5-page"
- x5-video-player-fullscreen="true"
- playsinline
- @click="handleVideoClicked"
- >
- </video>
- <span v-show="!isPlay" class="btn__play" @click="handleVideoClicked"><i class="iconfont icon-bofang"></i></span>
- </div>
- <!-- ///信息模块 -->
- <div class="swipe__vdinfo flexbox flex-col">
- <div class="flexbox flex-alignb">
- <!-- ///底部信息栏 -->
- <div class="swipe__footbar flex1">
- ...
- </div>
- <!-- ///右侧工具栏 -->
- <div class="swipe__toolbar">
- ...
- </div>
- </div>
- </div>
- </van-swipe-item>
- </van-swipe>
- </template>
- </van-swipe-item>
- </van-swipe>
- <!-- ///底部进度条 -->
- <div class="swipe__progress"><i class="bar" :style="{'width': vdProgress+'%'}"></i></div>
- </div>
- </div>
- <!-- >>底部TabBar -->
- <tabbar
- bgcolor="linear-gradient(to bottom, transparent, rgba(0,0,0,.6))"
- color="rgba(255,255,255,.6)"
- activeColor="#fff"
- fixed
- />
- <!-- …… -->
- </div>
- </template>
- <script>
- /**
- * @Desc Vue3.0实现小视频功能
- * @Time andy by 2021-02
- * @About Q:282310962 wx:xy190310
- */
- import { onMounted, onUnmounted, ref, reactive, toRefs, inject, nextTick } from 'vue'
- ...
- export default {
- components: {
- CmtEditor,
- },
- setup() {
- // 定时器
- const vdTimer = ref(null)
- const tapTimer = ref(null)
- const swipeHorizontalRef = ref(null)
- const editorRef = ref(null)
- const v3popup = inject('v3popup')
- const data = reactive({
- // ...
- })
- onMounted(() => {
- swipeHorizontalRef.value.swipeTo(data.activeNav, {immediate: true})
- // ...
- })
- // ...
- // 垂直切换页面事件
- const handleSwipeVertical = (index) => {
- if(data.activeNav == 0) {
- // 附近页
- data.activeOneIdx = index
- }else if(data.activeNav == 1) {
- // 关注页
- data.activeTwoIdx = index
- }else if(data.activeNav == 2) {
- // 推荐页
- data.activeThreeIdx = index
- }
- vdTimer.value && clearInterval(vdTimer.value)
- data.vdProgress = 0
- data.isPlay = false
- let video = getVideoContext()
- if(!video) return
- video.pause()
- // 重新开始
- video.currentTime = 0
- data.activeSwipeIndex = index
- // 自动播放下一个
- handlePlay()
- }
- // 播放
- const handlePlay = () => {
- let video = getVideoContext()
- if(!video) return
- video.play()
- data.isPlay = true
- // 设置进度条
- vdTimer.value = setInterval(() => {
- handleProgress()
- }, 16)
- }
- // 暂停
- const handlePause = () => {
- let video = getVideoContext()
- if(!video) return
- video.pause()
- data.isPlay = false
- vdTimer.value && clearInterval(vdTimer.value)
- }
- // 视频点击事件(判断单/双击)
- const handleVideoClicked = () => {
- tapTimer.value && clearTimeout(tapTimer.value)
- data.clickNum++
- tapTimer.value = setTimeout(() => {
- if(data.clickNum >= 2) {
- console.log('双击事件')
- }else {
- console.log('单击事件')
- if(data.isPlay) {
- handlePause()
- }else {
- handlePlay()
- }
- }
- data.clickNum = 0
- }, 300)
- }
- // 播放进度条
- const handleProgress = () => {
- let video = getVideoContext()
- if(!video) return
- let curTime = video.currentTime.toFixed(1)
- let duration = video.duration.toFixed(1)
- data.vdProgress = parseInt((curTime / duration).toFixed(2) * 100)
- }
- // ...
- return {
- ...toRefs(data),
- // ...
- }
- }
- }
- </script>
复制代码
另外项目中所有的弹窗功能,均是vue3自定义移动端弹框v3popup组件来实现。
vue3系列:vue3.0自定义弹框组件V3Popup|vue3.x手机端弹框组件
Ending,运用vue3+vant3开发仿抖音小视频/直播实战就分享到这里。希望大家喜欢哈!
|
|