
项目介绍:
今天给大家分享的一个项目是基于uniapp+vue+nvue技术开发的仿抖音小视频|陌陌直播项目,界面效果类似抖音,可实现上下滑动切换小视频播放,还有点赞、评论及商品广告等功能,支持编译到H5、小程序、App端。
效果预览:
分别是在H5端、小程序、App端及真机下效果,后续均展示App效果图

技术实现:
-
编辑器/技术:HBuilderX + vue/NVue/uniapp/vuex
-
字体图标:阿里iconfont字体图标库
-
自定义导航栏 + 底部Tabbar
-
弹窗组件:uniPop(uni-app封装自定义Modal弹窗)
-
测试环境:H5端/小程序/App端/真机





















自定义导航模式:App.vue获取顶部状态栏高度
<script>import Vue from 'vue'export default {onLaunch: function() {// console.log('App Launch')uni.getSystemInfo({success:function(e){Vue.prototype.statusBar = e.statusBarHeight// #ifndef MPif(e.platform == 'android') {Vue.prototype.customBar = e.statusBarHeight + 50}else {Vue.prototype.customBar = e.statusBarHeight + 45}// #endif// #ifdef MP-WEIXINlet custom = wx.getMenuButtonBoundingClientRect()Vue.prototype.customBar = custom.bottom + custom.top - e.statusBarHeight// #endif// #ifdef MP-ALIPAYVue.prototype.customBar = e.statusBarHeight + e.titleBarHeight// #endif}})},}</script>
Nvue页面中引入阿里字体图标,和vue页面不一样,不能单单使用<text class="iconfont icon-search"></text>这种方式引入,会在手机无法显示图标,需要通过Unicode字符方式
调用方式:<text class="nvueIcon"></text>
beforeCreate() {// 引入iconfont字体// #ifdef APP-PLUSconst domModule = weex.requireModule('dom')domModule.addRule('fontFace', {fontFamily: "nvueIcon",'src': "url('../../../static/fonts/iconfont.ttf')"});// #endif},
main.js引入公共组件及样式库
import Vue from 'vue'import App from './App'import './static/fonts/iconfont.css'import './assets/css/reset.css'import './assets/css/layout.css'// 状态管理import store from './store'Vue.prototype.$store = store// 公共组件import headerBar from './components/header/header.vue'import tabBar from './components/tabbar/tabbar.vue'import popupWindow from './components/popupWindow.vue'Vue.component('header-bar', headerBar)Vue.component('tab-bar', tabBar)Vue.component('popup-window', popupWindow)// 自定义弹窗组件import uniPop from './components/uniPop/uniPop.vue'Vue.component('uni-pop', uniPop)Vue.config.productionTip = falseApp.mpType = 'app'const app = new Vue({...App})app.$mount()
另外消息模块聊天功能,可参考之前这篇文章:
uni-app聊天App实例|vue+uniapp仿微信界面|红包|朋友圈
uniapp+swiper组件实现抖音上下滑动切换效果,可点击播放、暂停。

<swiper :indicator-dots="false" :duration="200" :vertical="true" :current="videoIndex" @change="handleSlider" style="height: 100%;"><block v-for="(item,index) in vlist" :key="index"><swiper-item><view class="uni_vdplayer"><video :id="'myVideo' + index" :ref="'myVideo' + index" class="player-video" :src="item.src":controls="false" :loop="true" :show-center-play-btn="false" objectFit="fill"></video><!-- 中间播放按钮 --><view class="vd-cover flexbox" @click="handleClicked(index)"><text v-if="!isPlay" class="iconfont icon-bofang"></text></view><!-- 底部信息 --><view class="vd-footToolbar flexbox flex_alignb"><view class="vd-info flex1"><view class="item at"><view class="kw" v-for="(kwItem,kwIndex) in item.keyword" :key="kwIndex"><text class="bold fs_18 mr_5">#</text> {{kwItem}}</view></view><view class="item subtext">{{item.subtitle}}</view><view class="item uinfo flexbox flex_alignc"><image class="avator" :src="item.avator" mode="aspectFill" /><text class="name">{{item.author}}</text> <text class="btn-attention bg_linear1" :class="item.attention ? 'on' : ''" @tap="handleAttention(index)">{{item.attention ? '已关注' : '关注'}}</text></view><view class="item reply" @tap="handleVideoComment"><text class="iconfont icon-pinglun mr_5"></text> 写评论...</view></view><view class="vd-sidebar"><view v-if="item.cart" class="ls cart flexbox bg_linear3" @tap="handleVideoCart(index)"><text class="iconfont icon-cart"></text></view><view class="ls" @tap="handleIsLike(index)"><text class="iconfont icon-like" :class="item.islike ? 'like' : ''"></text><text class="num">{{ item.likeNum+(item.islike ? 1: 0) }}</text></view><view class="ls" @tap="handleVideoComment"><text class="iconfont icon-liuyan"></text><text class="num">{{item.replyNum}}</text></view><view class="ls"><text class="iconfont icon-share"></text><text class="num">{{item.shareNum}}</text></view></view></view></view></swiper-item></block></swiper>
<script>const videoJson = require('./mock-video.js')// 引入商品广告、评论import videoCart from '@/components/cp-video/cart.vue'import videoComment from '@/components/cp-video/comment'let timer = nullexport default {data() {return {videoIndex: 0,vlist: videoJson,isPlay: true, //当前视频是否播放中clickNum: 0, //记录点击次数}},components: {videoCart, videoComment},onLoad(option) {this.videoIndex = parseInt(option.index)},onReady() {this.init()},methods: {init() {this.videoContextList = []for(var i = 0; i < this.vlist.length; i++) {// this.videoContextList.push(this.$refs['myVideo' + i][0])this.videoContextList.push(uni.createVideoContext('myVideo' + i, this));}setTimeout(() => {this.play(this.videoIndex)}, 200)},// 滑动切换handleSlider(e) {let curIndex = e.detail.currentif(this.videoIndex >= 0){this.videoContextList[this.videoIndex].pause()this.videoContextList[this.videoIndex].seek(0)this.isPlay = false}if(curIndex === this.videoIndex + 1) {this.videoContextList[this.videoIndex + 1].play()this.isPlay = true}else if(curIndex === this.videoIndex - 1) {this.videoContextList[this.videoIndex - 1].play()this.isPlay = true}this.videoIndex = curIndex},// 播放play(index) {this.videoContextList[index].play()this.isPlay = true},// 暂停pause(index) {this.videoContextList[index].pause()this.isPlay = false},// 喜欢handleIsLike(index){let vlist = this.vlistvlist[index].islike =! vlist[index].islikethis.vlist = vlist},// 显示评论handleVideoComment() {this.$refs.videoComment.show()},// 显示购物车handleVideoCart(index) {this.$refs.videoCart.show(index)},}}</script>
由于原生video层级过高,view组件不能覆盖其上,可以使用cover-view,不过该组件不能内嵌其他组件,故可采用nvue页面模式,nvue和vue页面结构基本一致,不过编写需要注意css样式,不能使用多个css选择器,只能单个定义。

文章评论