为了账号安全,请及时绑定邮箱和手机立即绑定

基于Vue3.x+Vant3高仿抖音|火山APP小视频|直播

标签:
Vue.js vuex MVVM

​随着抖音再一次获得2021辛丑牛年春晚独家红包合作赞助商。短视频/直播即将又再一次刷爆网络,成为新一代中国人的娱乐方式。💖

项目简介

基于vite2搭建的vue3短视频+直播实例项目Vue3_Douyin,使用了Vue3.0.5+Vuex+VueRouter+Vant3+V3Popup等技术来构建开发。
图片描述

支持滑动切换视频/直播、点赞/评论、聊天/弹幕/送礼物/红包等功能。

图片描述

实现技术

  • 构建工具:vite.js
  • vue3全家桶:vue3.0.5+vue-router@4+vuex4
  • 组件库:vant3 (有赞移动端vue3.0组件库)
  • 弹层组件:v3popup(移动端vue3弹框组件)
  • 字体图标:阿里iconfont图标
  • 导航栏/标签栏:自定义顶部Navbar+底部Tabbar组件

图片描述

目录结构

图片描述

这个项目基于vue3最新语法来编码开发,遵循vue3标准式语法结构。

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

图片描述

大家看到的所有弹窗应用场景,均是基于vue3开发的自定义组件v3popup来实现功能。

图片描述

之前有过一些分享,这里就不介绍了。感兴趣的可以去看看历史文章。

vite.config.js项目配置

/**
 * Vite2项目配置
 */

import vue from '@vitejs/plugin-vue'

import path from 'path'

/**
 * @type {import('vite').UserConfig}
 */
export default {
  plugins: [vue()],

  build: {
    // 基本目录
    // base: '/',

    /**
     * 输出文件目录
     * @default dist(默认)
     */
    // outDir: 'target',
  },

  // 环境配置
  server: {
    // 自定义接口
    port: 3000,

    // 是否自动浏览器打开
    open: false,

    // 是否开启https
    https: false,

    // 代理配置
    proxy: {
        // ...
    }
  },

  // 设置路径别名
  alias: {
    '@': path.resolve(__dirname, './src'),
    '@components': path.resolve(__dirname, './src/components'),
    '@views': path.resolve(__dirname, './src/views')
  }
}

使用vite.js构建的项目都会有一个配置文件,进行一些简单的项目环境及路径配置。

vue3引入公共插件

为了使得项目结构更加清晰,新建一个plugings.js页面用来引入一些常用的公共插件。

/**
 * 引入公共组件
 */

// 引入Vant3.x组件库
import Vant from 'vant'
import 'vant/lib/index.css'

// 引入Vue3.x移动端弹层组件
import V3Popup from '@components/v3popup'

import NavBar from '@components/navBar.vue'
import TabBar from '@components/tabBar.vue'

import Utils from './utils'
import Storage from './storage'

const Plugins = (app) => {
    app.use(Vant)
    app.use(V3Popup)

    // 注册公用组件
    app.component('navbar', NavBar)
    app.component('tabbar', TabBar)

    app.provide('utils', Utils)
    app.provide('storage', Storage)
}

vue3小视频/直播模板

项目中的短视频和直播模板有一些地方是公共的,都是使用了swipe组件来滑动切换效果。首页小视频可以上下左右滑动,直播页面上下滑动。
图片描述

<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"
                                            :class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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 v-if="item2.ads" class="item swipe__superlk ads" @click="handleOpenLink(item2)">
                                                    <i class="iconfont icon-copylink fs-28"></i>查看详情<i class="iconfont icon-arrR fs-24"></i>
                                                </div>
                                                <div v-if="item2.collectionLs&&item2.collectionLs.length>0" class="item swipe__superlk">
                                                    <i class="iconfont icon-copylink fs-24 mr-10"></i><div class="flex1">合集《小鬼当家》主演花絮</div><i class="iconfont icon-arrR fs-24"></i>
                                                </div>
                                                <div class="item uinfo flexbox flex-alignc">
                                                    <router-link to="/friend/uhome"><img class="avatar" :class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="item2.avatar" /></router-link>
                                                    <router-link to="/friend/uhome"><em class="name">{{item2.author}}</em></router-link>
                                                    <button class="btn vui__btn vui__btn-primary" :class="item2.isFollow ? 'isfollow' : ''" @click="handleIsFollow(item.category, index2)">{{item2.isFollow ? '已关注' : '关注'}}</button>
                                                </div>
                                                <div class="item at">@{{item2.author}}</div>
                                                <div v-if="item2.topic" class="item kw"><em v-for="(kw,idx) in item2.topic" :key="idx">#{{kw}}</em></div>
                                                <div class="item desc">{{item2.desc}}</div>
                                            </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
        />


        <!-- ……商品模板 -->
        <v3-popup v-model="isShowGoodsPopup" position="bottom" round xclose title="热销商品" @end="handlePopStateClose" opacity=".2">
            <div v-if="goodsLs" class="wrap_goodsList">
                ...
            </div>
        </v3-popup>

        <!-- ……评论列表模板 -->
        <v3-popup v-model="isShowReplyPopup" position="bottom" round xclose opacity=".2">
            <div class="nt__commentWrap">
                <!-- 评论列表 -->
                ...
            </div>
        </v3-popup>
        <!-- ……评论编辑器模板 -->
        <v3-popup v-model="isShowReplyEditor" position="bottom" opacity=".2">
            <div class="vui__footTool nt__commentWrap">
                ...
            </div>
        </v3-popup>

        <!-- ……分享模板 -->
        <v3-popup v-model="isShowSharePopup" anim="footer" type="actionsheet" round xclose opacity=".2"
            title="<div style='text-align:left;'>分享至</div>"
            :btns="[
                {text: '取消', style: 'color:#999;', click: () => isShowSharePopup=false},
            ]"
        >
            ...
        </v3-popup>
    </div>
</template>

当视频列表多的时候,设置lazy-render属性,会延迟加载下一页视频数据,大大的提升滑动性能。

图片描述

如上图:送礼物|充值弹窗是使用v3popup组件的自定义插槽来实现功能。

ending,运用vue3.x+vant3开发火山/抖音短视频|直播项目就分享到这里。
后面还会分享一些vue3.0实战案例,多谢大家的支持哈~~

图片描述

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
28
获赞与收藏
94

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消