基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能


Posted in Javascript onNovember 12, 2019

一、项目简介

uni-liveShow是一个基于vue+uni-app技术开发的集小视频/IM聊天/直播等功能于一体的微直播项目。界面仿制抖音|火山小视频/陌陌直播,支持编译到多端(H5、小程序、App端) 且兼容效果一致。

二、效果预览

在H5、小程序、App端测试效果如下:(后续大图均为APP端)

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

三、使用技术

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

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

◆ uniapp计算设备顶部状态栏高度

/**
 * @desc uniapp主页面App.vue
 * @about Q:282310962 wx:xy190310
 */

<script>
 import Vue from 'vue'
 export default {
 onLaunch: function() {
 // console.log('App Launch')
 uni.getSystemInfo({
 success:function(e){
 Vue.prototype.statusBar = e.statusBarHeight
 // #ifndef MP
 if(e.platform == 'android') {
 Vue.prototype.customBar = e.statusBarHeight + 50
 }else {
 Vue.prototype.customBar = e.statusBarHeight + 45
 }
 // #endif
 
 // #ifdef MP-WEIXIN
 let custom = wx.getMenuButtonBoundingClientRect()
 Vue.prototype.customBar = custom.bottom + custom.top - e.statusBarHeight
 // #endif
 
 // #ifdef MP-ALIPAY
 Vue.prototype.customBar = e.statusBarHeight + e.titleBarHeight
 // #endif
 }
 })
 },
 }
</script>

◆ 项目中顶部透明导航栏设置

顶部导航栏采用的是自定义模式,可设置透明背景(如:个人主页/朋友圈动态) 具体可参看这篇文章:https://3water.com/article/174034.htm

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

<header-bar :isBack="true" title=" " :bgColor="{background: 'transparent'}" transparent>
 <text slot="back" class="uni_btnIco iconfont icon-guanbi" style="font-size: 25px;"></text>
 <text slot="iconfont" class="uni_btnIco iconfont icon-dots mr_5" style="font-size: 25px;"></text>
</header-bar>

◆ uniapp仿抖音小视频效果

项目中小视频界面功能效果类似抖音/火山小视频,使用swiper组件实现上下滑动切换视频播放。

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

<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>
 // 引入商品广告、评论
 import videoCart from '@/components/cp-video/cart.vue'
 import videoComment from '@/components/cp-video/comment'
 
 let timer = null
 export 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.current
 if(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
 },
 // 点击视频事件
 handleClicked(index) {
 if(timer){
 clearTimeout(timer)
 }
 this.clickNum++
 timer = setTimeout(() => {
 if(this.clickNum >= 2){
 console.log('双击视频')
 }else{
 console.log('单击视频')
 if(this.isPlay){
 this.pause(index)
 }else{
 this.play(index)
 }
 }
 this.clickNum = 0
 }, 300)
 },
 
 
 // 喜欢
 handleIsLike(index){
 let vlist = this.vlist
 vlist[index].islike =! vlist[index].islike
 this.vlist = vlist
 },
 // 显示评论
 handleVideoComment() {
 this.$refs.videoComment.show()
 },
 
 // 显示购物车
 handleVideoCart(index) {
 this.$refs.videoCart.show(index)
 },
 }
 }
</script>

在项目开发过程中,遇到了视频video层级高不能覆盖的问题,使用nvue页面就可以解决view覆盖在video之上。.nvue(native vue的缩写)

更多关于nvue页面开发,可以参看:uniapp开发nvue页面

◆ uniapp聊天页面实现

项目中的聊天页面,功能效果这里就不详细介绍了,可参看这篇:uni-app聊天室|vue+uniapp仿微信聊天实例

◆ 直播页面live.nvue

为避免video不能覆盖问题,直播页面采用的是nvue编写,开发过程也遇到了一些坑,尤其是css,全部是flex布局,而且不能多级嵌套,有些css属性不支持。

基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能

<template>
 <div class="nlv__container">
 <view class="nlv_main">
 <swiper class="nlv-swiper" :indicator-dots="false" :vertical="false" :current="videoIndex" @change="handleSlider">
 <swiper-item v-for="(item, index) in vlist" :key="index">
 <!-- //直播区 -->
 <view class="nlv-playerbox">
 <video :id="'myVideo' + index" :ref="'myVideo' + index" class="player-video" :src="item.src" :autoplay="index == videoIndex"
 :controls="false" :loop="true" :show-center-play-btn="false" objectFit="fill" :style="{height: winHeight, width: winWidth}">
 </video>
 
 <!-- //顶部 -->
 <view class="nlv_topbar" :style="{ height: headerBarH, 'padding-top': statusBarH }">
 ...
 </view>
 
 <!-- //排名信息 -->
 <view class="nlv-rankbox" :style="{top: headerBarH}">
 <view class="nlv-rkls">
 <text class="rkitem">总排名{{item.allRank}}</text>
 <text v-if="item.hourRank" class="rkitem">小时榜第{{item.hourRank}}名</text>
 </view>
 <text class="nlv-uid">U直播:{{item.uid}}</text>
 </view>
 
 <!-- //底部信息栏 -->
 <view class="nlv-footToolbar">
 <!-- 送礼物提示 -->
 <view class="nlv-giftTipPanel">
 ...
 </view>
 
 <!-- 滚动msg信息 -->
 <scroll-view class="nlv-rollMsgPanel" scroll-y show-scrollbar="false">
 <block v-for="(msgitem, msgidx) in item.rollmsg" :key="msgidx">
  <view class="nlv-msglist"><view class="msg_bg"><text class="msg_name">{{msgitem.uname}}</text> <text class="msg_text">{{msgitem.content}}</text></view></view>
 </block>
 </scroll-view>
 
 <view class="nlv-infobox">
 <view class="nlv_reply" @tap="handleRollMsg(index)"><text class="nlv_reply_text">说点什么...</text></view>
 <view class="nlv_btntool">
  ...
  <view v-if="item.cart" class="btn-toolitem" @tap="handleLiveCart(index)"><text class="iconfont i-btntool" style="color: #ff4e0e;font-size: 20px;"></text></view>
  <view class="btn-toolitem btn-toolitem-cart" @tap="handleLiveGift"><text class="iconfont i-btntool"></text></view>
  ...
 </view>
 </view>
 </view>
 </view>
 </swiper-item>
 </swiper>
 </view>
 
 <!-- 商品广告、滚动消息、礼物 -->
 <live-cart ref="liveCart" :vlist="vlist" />
 <roll-msg ref="rollMsg" :vlist="vlist" />
 <live-gift ref="liveGift" />
 </div>
</template>

另外引入阿里字体图标也需注意:通过weex方式引入

beforeCreate() {
 // 引入iconfont字体
 // #ifdef APP-PLUS
 const domModule = weex.requireModule('dom')
 domModule.addRule('fontFace', {
 fontFamily: "nvueIcon",
 'src': "url('../../../static/fonts/iconfont.ttf')"
 });
 // #endif
},

至于视频滑动切换和上面小视频操作差不多,就不贴码了。到这里,uni-liveShow项目基本介绍完了,希望对大家有些许帮助。?

最后,附上两个vue/react项目案例:

vue+vuex+vue-router仿微信网页版聊天室https://3water.com/article/160487.htm

angular+ng-router手机端聊天IM实战开发https://3water.com/article/71356.htm

总结

以上所述是小编给大家介绍的基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JavaScript 数组的 uniq 方法
Jan 23 Javascript
调用jQuery滑出效果时闪烁的解决方法
Mar 27 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
Jun 19 Javascript
js实现div层缓慢收缩与展开的方法
May 11 Javascript
javascript实现行拖动的方法
May 27 Javascript
Bootstrap实现默认导航栏效果
Sep 21 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
Aug 23 Javascript
JavaScript中捕获与冒泡详解及实例
Feb 03 Javascript
React组件重构之嵌套+继承及高阶组件详解
Jul 19 Javascript
基于JavaScript实现一个简单的Vue
Sep 26 Javascript
js获取浏览器地址(获取第1个斜杠后的内容)
Sep 03 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
Nov 14 Javascript
vuex管理状态 刷新页面保持不被清空的解决方案
Nov 11 #Javascript
vuex实现数据状态持久化
Nov 11 #Javascript
vue 更改连接后台的api示例
Nov 11 #Javascript
vue路由守卫,限制前端页面访问权限的例子
Nov 11 #Javascript
vue在路由中验证token是否存在的简单实现
Nov 11 #Javascript
vuex存储token示例
Nov 11 #Javascript
Vuex实现数据增加和删除功能
Nov 11 #Javascript
You might like
【动漫杂谈】关于《请在T台上微笑》
2020/03/03 日漫
ajax php传递和接收变量实现思路及代码
2012/12/19 PHP
php跨站攻击实例分析
2014/10/28 PHP
php 可变函数使用小结
2018/06/12 PHP
Laravel如何实现适合Api的异常处理响应格式
2020/06/14 PHP
提升你网站水平的jQuery插件集合推荐
2011/04/19 Javascript
JS获取url链接字符串 location.href
2013/12/23 Javascript
js定时调用方法成功后并停止调用示例
2014/04/08 Javascript
AngularJS语法详解(续)
2015/01/23 Javascript
JavaScript数据推送Comet技术详解
2016/04/07 Javascript
javascript二维数组和对象的深拷贝与浅拷贝实例分析
2019/10/26 Javascript
写了个监控nginx进程的Python脚本
2012/05/10 Python
Python实现的二维码生成小软件
2014/07/11 Python
python统计字符串中指定字符出现次数的方法
2015/04/04 Python
python计算方程式根的方法
2015/05/07 Python
Python 基于Twisted框架的文件夹网络传输源码
2016/08/28 Python
20招让你的Python飞起来!
2016/09/27 Python
python操作oracle的完整教程分享
2018/01/30 Python
基于数据归一化以及Python实现方式
2018/07/11 Python
python学习之hook钩子的原理和使用
2018/10/25 Python
浅谈Python反射 &amp; 单例模式
2019/03/21 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
python数据预处理方式 :数据降维
2020/02/24 Python
Keras-多输入多输出实例(多任务)
2020/06/22 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
你不知道的5个HTML5新功能
2016/06/28 HTML / CSS
a标签下载链接的简单实现
2016/09/13 HTML / CSS
美国在线精品家居网站:Burke Decor
2017/04/12 全球购物
中学教师实习自我鉴定
2013/09/28 职场文书
庆祝教师节演讲稿
2014/09/03 职场文书
检察机关个人对照检查材料
2014/09/15 职场文书
《我爱祖国》演讲稿1000字
2014/09/26 职场文书
2016年春季运动会通讯稿
2015/11/25 职场文书
创业计划书之寿司
2019/07/19 职场文书
教你怎么用Python生成九宫格照片
2021/05/20 Python
Python编写车票订购系统 Python实现快递收费系统
2022/08/14 Python