|  | 
 
| 介绍 vue3Douyin 是一款基于vite2构建工具搭建开发的vue3仿制抖音实战项目。使用了vue3.0+vuex+vant3+v3popup等技术编码开发,实现小视频上下滑动切换、点赞/评论/分享等功能。
 
   
 小视频页有附近/关注/推荐三大模块,可以实现左右及上下滑动切换效果。
 
 
   
 如上图:这个是原型设计,最终效果是下面这些展示图片。
 
 
   
 
   
 
   
 
   
 
   
 实现技术
 
 构建工具:Vite.js编辑器:VscodeMVVM框架:Vue^3.0.5状态管理:Vuex^4.0.0-rc.2页面路由:Vue-Router^4.0.3UI组件库: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开发仿抖音小视频/直播实战就分享到这里。希望大家喜欢哈!
  
 
 | 
 |