最新版uniapp+vue3+uv-ui跨端仿抖音短视频+直播+聊天【H5+小程序+App端】
原创uni-app+vue3+pinia2+uv-ui实战仿抖音app小视频+直播+聊天系统。
uni-vue3-welive:最新研发uniapp+vue3从0-1实战搭建仿抖音/微信直播带货商城。集短视频+聊天+直播功能于一体。实现全屏沉浸式切换短视频/直播,支持编译运行到h5+小程序端+app端。
运行效果
编译到小程序+h5+app端效果如下:

技术栈
- 编辑器:HbuilderX 4.66
- 框架技术:Uniapp+Vue3+Vite5+Nvue+Pinia2
- UI组件库:uv-ui+vk-uview
- 弹框组件:uaPopup(uniapp封装多端弹框组件)
- 自定义组件:uaNavbar+uaTabbar组件
- 本地缓存:pinia-plugin-unistorage
- 编译支持:h5+小程序+APP端


uni-vue3-welive实现丝滑般滑动体验,全屏沉浸式tabbar切换,微型迷你拖拽播放时间进度条等功能。


项目框架结构
使用uni-app+vue3搭建项目框架,采用vue3 setup语法编码开发。

目前uniapp-welive短视频直播项目已经同步到我的原创作品集。























uniapp跨端自定义navbar+tabbar组件
在components目录下自定义navbar、tabbar组件。

之前有过一篇分享文章,感兴趣的话也可以去看看,这里就不详细的介绍实现过程了。
https://www.cnblogs.com/xiaoyan2017/p/14978408.html
uniapp+vue3短视频模块

短视频模块采用全屏沉浸式上下无缝衔接滑动效果。整体分为顶部固定tabs+视频区+底部视频信息浮层三大模块。
<ua-layout>
<view class="ua__swipervideo flex1">
<swiper
class="ua__swipervideo-wrap flex1"
:current="currentVideo"
vertical
:circular="true"
:duration="200"
@change="handleChange"
@transition="handleTransition"
>
<swiper-item v-for="(item, index) in videoList" :key="index">
<video
class="ua__swipervideo-player flex1"
:id="'uplayer' + index"
:src="item.src"
:danmu-list="item.danmu"
:enable-danmu="true"
:controls="false"
:loop="true"
:autoplay="index == currentVideo"
:show-center-play-btn="false"
object-fit="contain"
@click="handleClickVideo"
@play="isPlaying=true"
@timeupdate="handleTimeUpdate"
:style="{'width': `${winWidth}px`, 'height': `${winHeight}px`}"
>
</video> <!-- 浮层模块 -->
<view class="ulive__video-float__info flexbox flex-col">
<view class="flexbox flex-row flex-alignb">
<!-- 左侧 -->
<view class="vdinfo__left flex1 flexbox flex-col">
<view class="ltrow danmu flexbox" @click="handleOpenDanmu"><text class="danmu-txt">弹</text><uv-icon class="ico" name="edit-pen" color="#fff" size="14" /></view>
<view class="ltrow"><text class="ait">@{{item.author}}</text></view>
<view class="ltrow"><text class="desc">{{item.desc}}</text></view>
</view>
<!-- 右侧操作栏 -->
<view class="vdinfo__right flexbox flex-col">
<view class="rtbtn avatar flexbox flex-col">
<view class="ubox"><image class="uimg" :src="item.avatar" mode="aspectFill" /></view>
<view class="btn flexbox" :class="{'active': item.isFollow}" @click="handleFollow(index)"><uv-icon :name="item.isFollow ? 'checkmark' : 'plus'" :color="item.isFollow ? '#ff007f' : '#fff'" size="11" /></view>
</view>
<view class="rtbtn flexbox flex-col" @click="handleLiked(index)"><uv-icon name="heart-fill" :color="item.isLike ? '#ff007f' : '#fff'" size="40" /><text class="num">{{item.likeNum+(item.isLike ? 1 : 0)}}</text></view>
<view class="rtbtn flexbox flex-col" @click="handleOpenComment(index)"><uv-icon name="chat-fill" color="#fff" size="40" /><text class="num">{{item.replyNum}}</text></view>
<view class="rtbtn flexbox flex-col"><uv-icon name="star-fill" color="#fff" size="40" /><text class="num">{{item.starNum}}</text></view>
<view class="rtbtn flexbox flex-col" @click="handleOpenShare(index)"><uv-icon name="share-fill" color="#fff" size="40" /><text class="num">{{item.shareNum}}</text></view>
</view>
</view>
</view>
</swiper-item>
</swiper> <!-- 固定tabs(脱离滑动区) -->
<view class="ulive__video-header__tabs" :style="{'margin-top': `${menuBarT}px`}">
<uv-tabs :current="tabsCurrent" :list="tabsList" />
</view> <!-- 播放暂停按钮 -->
<view v-if="!isPlaying" class="ua__swipervideo-playbtn" :style="{'left': `${winWidth/2}px`, 'top': `${winHeight/2}px`}" @click="handleClickVideo">
<text class="ua__swipervideo-playico welive-icon welive-icon-play nvueicon"></text>
</view> <!-- 播放mini进度条 -->
<view v-if="sliderValue > 0" class="ua__swipervideo-slider">
<slider
:value="sliderValue"
:step="sliderStep"
:max="sliderMaxValue"
activeColor="#fff"
backgroundColor="rgba(255,255,255,.2)"
block-color="#fff"
block-size="6"
@changing="onSliderChanging"
@change="onSliderChange"
/>
</view>
</view> <template #footer>
<ua-tabbar bgcolor="transparent" color="rgba(255,255,255,.7)" :border="false" :dock="false" transparent z-index="1000" />
</template>
</ua-layout>

// 监听播放进度条
const handleTimeUpdate = (e) => {
let { currentTime, duration } = e.detail
sliderValue.value = currentTime
sliderMaxValue.value = duration
sliderStep.value = currentTime / duration
} // 滑动条拖动中
const onSliderChanging = (e) => {
sliderValue.value = e.detail.value
handlePause()
} // 滑动条拖动结束
const onSliderChange = (e) => {
sliderValue.value = e.detail.value
let video = getVideoContext()
if(!video) return
video.seek(sliderValue.value)
handlePlay()
}
uniapp+vue3仿微信app聊天模块

聊天功能模块是之前uniapp+vue3仿微信app聊天项目的迁移模块。如果对聊天项目感兴趣,可以去看看下面这篇分享文章。
uniapp+vue3聊天室|uni-app+vite4+uv-ui跨端仿微信app聊天语音/朋友圈

uni-app+vue3直播模块

直播模块整体分为顶部信息+直播流视频区+滚动消息(加入直播间+送礼物+讲解商品)+底部工具栏
<ua-layout>
<view class="ua__swipervideo flex1">
<swiper
class="ua__swipervideo-wrap flex1"
:current="currentLive"
vertical
@change="handleChange"
>
<swiper-item v-for="(item, index) in liveList" :key="index">
<video
class="ua__swipervideo-player flex1"
:id="'uplayer' + index"
:src="item.src"
:controls="false"
:loop="true"
:autoplay="index == currentLive"
:show-center-play-btn="false"
object-fit="contain"
:style="{'width': `${winWidth}px`, 'height': `${winHeight}px`}"
>
</video> <!-- 浮层模块 -->
<swiper class="ulive__swiperscreen flex1" :current="1">
<!-- 清屏 -->
<swiper-item>
第一屏
</swiper-item>
<swiper-item>
<!-- 顶部区域 -->
<view class="ulive__headlayer" :style="{'top': menuBarT+'px'}">
<!-- logo+关注 -->
<view class="ulive__hd-liveinfo flexbox flex-row flex-alignc">
<view class="ulive__hd-avatar ulive__mask flex-alignc">
<image class="logo" :src="item.logo" mode="widthFix" />
<view class="flex1 flexbox flex-col ml-10">
<text class="name">{{item.name}}</text>
<text class="zan">{{item.likeNum}}本场点赞</text>
</view>
<view class="btn flexbox flex-row flex-alignc" :class="{'active': item.isFollow}" @click="handleFollow(index)"><text class="btntext" :class="{'active': item.isFollow}">{{item.isFollow ? '已关注' : '关注'}}</text></view>
</view>
<view class="ulive__hd-onlineuser flex1">
<uv-icon name="close" color="#fff" @click="handleLiveQuit" />
</view>
</view>
<view class="ulive__hd-livewrap flexbox flex-row">
<view class="ulive__hd-livewrap__left flex1 flexbox flex-col">
<view class="ulive__hd-livewrap__tags flexbox flex-row">
<view class="ulive__roundwrap ulive__mask">
<uv-icon name="shopping-cart" color="#ffdd1a" /><text class="ulive__roundtext">服饰鞋包榜第1名</text>
</view>
<view class="ulive__roundwrap ulive__mask ml-10">
<uv-icon name="level" color="#ffdd1a" /><text class="ulive__roundtext">小时榜</text>
</view>
</view>
<!-- 红包+福袋倒计时 -->
<view class="ulive__hd-livewrap__redpacket flexbox flex-row">
<view class="ulive__redpacket-item ulive__mask" @click="handleOpenRedpacket(1)">
<image class="ulive__redpacket-image" src="/static/icon-fudai.png" mode="widthFix" /><text class="ulive__redpacket-time">04:49</text>
</view>
<view class="ulive__redpacket-item ulive__mask" @click="handleOpenRedpacket(2)">
<image class="ulive__redpacket-image" src="/static/icon-hb.png" mode="widthFix" /><text class="ulive__redpacket-time">04:49</text>
</view>
<view class="ulive__redpacket-item ulive__mask center">
<image class="ulive__redpacket-image" src="/static/icon-rotate.png" mode="widthFix" /><text class="ulive__redpacket-time">04:49</text>
</view>
</view>
</view>
<view class="ulive__hd-livewrap__right flexbox flex-col">
<view class="ulive__roundwrap ulive__mask mr-20">
<uv-icon name="kefu-ermai" color="#fff" /><text class="ulive__roundtext ml-5">后台</text>
</view>
</view>
</view>
</view> <!-- 底部区域 -->
<view class="ulive__footlayer">
<!-- 商品提示层 -->
<view class="ulive__ft-livewrap-placeholder animated fadeIn">
<view class="ulive__ft-livewrap-hotbuy flexbox flex-row">
<image class="gimg" :src="item.poster" mode="aspectFill" />
<view class="ginfo flex1">
<view class="flexbox flex-row"><text class="user c-ffdd1a">Andy</text><text class="c-fff">等{{item.saleNum}}人在购买</text></view>
<text class="gdesc clamp1">{{item.desc}}</text>
</view>
<view class="btn"><text class="btntext">去购买</text></view>
</view>
</view>
<!-- 加入直播间/送礼物提示 -->
<view class="ulive__ft-livewrap-animateview flexbox flex-col">
<view class="ulive__ft-livewrap-animatejoin ulive__ft-livewrap-placeholder">
<view v-if="joinRoomData" class="ulive__ft-livewrap-joinroom"><text class="ulive__ft-livewrap-joinroom__text">欢迎{{joinRoomData}}加入了直播间</text></view>
</view> <!-- 送礼物 -->
<view class="ulive__ft-livewrap-animategift ulive__ft-livewrap-placeholder">
<view v-if="!isEmpty(sendGiftData)" class="ulive__ft-livewrap-activegift flexbox flex-row flex-alignc">
<image class="avatar" :src="sendGiftData.avatar" />
<view class="info flex1"><text class="name">{{sendGiftData.user}}</text><text class="desc">送出</text></view>
<image class="gift" :src="sendGiftData.pic" />
</view>
</view>
</view>
<!-- 聊天浮层+商品讲解 -->
<view class="ulive__ft-livewrap-mixinview flexbox flex-row">
<!-- 聊天消息 -->
<view class="ulive__ft-livewrap-chats flex1">
<scroll-view class="ulive__ft-livewrap-chats__scrollview flex1" scroll-y show-scrollbar="false" :scroll-into-view="scrollToView" :lower-threshold="5" @scroll="handleMsgScroll" @scrolltolower="handleMsgScrollLower">
<block v-for="(msgitem, msgidx) in item.message" :key="msgidx">
<view v-if="msgitem.type == 'notice'" class="notice" :id="`msg-${msgitem.id}`"><view class="item"><text class="noticetext">{{msgitem.content}}</text></view></view>
<view v-else-if="msgitem.type == 'gift'" class="gift" :id="`msg-${msgitem.id}`">
<view class="item">
<text class="giftuser">{{msgitem.user}}</text>
<text class="gifttext">送出了{{msgitem.content}}</text>
<image class="giftimg" :src="msgitem.img" mode="widthFix" />
<text class="giftnum">x{{msgitem.num}}</text>
</view>
</view>
<view v-else class="msg" :id="`msg-${msgitem.id}`">
<view class="item">
<text v-if="msgitem.tag" class="tag">{{msgitem.tag}}</text>
<text class="user">{{msgitem.user}}</text>
<text class="text" :style="[fixTextStyle]">{{msgitem.isbuy ? '正在购买' : msgitem.content}}</text>
<text v-if="msgitem.isbuy" class="tag tag-buy">去购买</text>
</view>
</view>
</block>
</scroll-view>
<view v-if="!isEmpty(msgUnread)" class="ulive__ft-livewrap-chats__unread" @click="handleMsgIsRead"><text class="c-eb4868 fs-24">{{msgUnread.length}}条新消息</text></view>
</view>
<!-- 商品讲解 -->
<view v-if="isVisibleGoodsTalk" class="ulive__ft-livewrap-activegoods animated fadeInRight" id="goodsTalkID">
<view class="ulive__ft-livewrap-activegoods__hotsale flexbox flex-row">
<image class="fimg" src="/static/icon-hot.png" mode="widthFix" /><text class="c-fff fs-32">热卖 x{{item.saleNum}}</text>
</view>
<swiper class="ulive__ft-livewrap-activegoods__swiper">
<swiper-item>
<view class="ulive__ft-livewrap-activegoods__card">
<view class="gwrap" @click="toGoodsDetail">
<image class="gimg" :src="item.poster" mode="aspectFill" />
<view class="waves"><text class="c-fff fs-24">讲解中</text></view>
<view class="close" @click.stop="isVisibleGoodsTalk=false"><uv-icon name="close-circle-fill" color="rgba(0, 0, 0, .3)" size="14" /></view>
</view>
<view class="ginfo flexbox flex-col">
<text class="clamp1 fs-24">{{item.desc}}</text>
<text class="clamp1 fs-24 c-eb4868">7天无理由退货</text>
</view>
<view class="btn flexbox flex-row"><text class="flex1 c-fff fs-28">¥79.00</text><text class="qiang">抢</text></view>
</view>
</swiper-item>
</swiper>
</view>
</view>
<!-- 工具栏 -->
<view class="ulive__ft-livewrap-toolbar flexbox flex-row">
<view class="editorwrap flex1 flexbox flex-row flex-alignc">
<view class="flex1" @click="handleOpenChatbox"><text class="editorwrap-text">说点什么...</text></view>
</view>
<view class="btnwrap flexbox flex-row">
<view class="btn flexbox" @click="handleOpenMenus"><uv-icon name="grid" color="#3c9cff" size="22" /></view>
<view class="btn flexbox" @click="handleOpenGoods(item)"><uv-icon name="shopping-cart-fill" color="#ffaa00" size="24" /></view>
<view class="btn flexbox" @click="handleOpenGifts"><uv-icon name="gift" color="#ff0ad3" size="22" /></view>
<view class="btn flexbox"><uv-icon name="more-dot-fill" color="#efe9ff" size="18" /></view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</swiper-item>
</swiper>
</view>
</ua-layout>
综上就是uni-app+vue3+uv-ui搭建跨三端短视频+聊天+直播app应用的一些知识分享。希望对大家有些帮助!
最后附上几个最新项目实例
Tauri2.0-DeepSeek电脑端Ai对话|tauri2+vite6+deepseek流式ai聊天系统
Uniapp-DeepSeek跨三端AI助手|uniapp+vue3+deepseek-v3流式ai聊天模板
vue3-webseek网页版AI问答|Vite6+DeepSeek+Arco流式ai聊天打字效果
flutter3-dymall仿抖音直播商城|Flutter3.27短视频+直播+聊天App实例
Tauri2.0-Vue3OS桌面端os平台|tauri2+vite6+arco电脑版OS管理系统
uniapp+vue3酒店预订|vite5+uniapp预约订房系统模板(h5+小程序+App端)
Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天应用

最新版uniapp+vue3+uv-ui跨端仿抖音短视频+直播+聊天【H5+小程序+App端】的更多相关文章
- 基于uniapp自定义Navbar+Tabbar组件「兼容H5+小程序+App端Nvue」
uni-app跨端自定义navbar+tabbar组件|沉浸式导航条|仿咸鱼凸起标签栏 在跨端项目开发中,uniapp是个不错的框架.采用vue.js和小程序语法结构,使得入门开发更容易.拥有非常丰富 ...
- 基于uni-app全端弹框组件uaPopup「兼容h5+小程序+app端|nvue」
uniapp兼容多端自定义模态弹框组件UAPopup ua-popup 一款轻量级的uniapp自定义弹窗组件.汇集了android.ios和微信弹窗效果(msg消息.alert提示框.dialog对 ...
- uni-app仿抖音APP短视频+直播+聊天实例|uniapp全屏滑动小视频+直播
基于uniapp+uView-ui跨端H5+小程序+APP短视频|直播项目uni-ttLive. uni-ttLive一款全新基于uni-app技术开发的仿制抖音/快手短视频直播项目.支持全屏丝滑般上 ...
- 【实战】SpringBoot+uniapp+uview打造H5+小程序+APP入门学习的聊天小项目
JavaDog Chat v1.0.0 基于SpringBoot+uniapp简单通讯聊天软件 项目介绍 JavaDog Chat 简单通讯聊天软件是基于SpringBoot+MybatisPlus+ ...
- 10分钟快速上车短视频风口:基于uniapp框架创建自己的仿抖音短视APP
在今年也就是第48次发布的<中国互联网络发展状况统计报告>有这样一个数据,21年的上半年以来,我国我国网民规模达10.11亿,其中短视频用户达8.88亿.碎片化的生活场景下,短视频成为人们 ...
- 基于vue+uniapp直播项目|uni-app仿抖音/陌陌直播室
一.项目简介 uni-liveShow是一个基于vue+uni-app技术开发的集小视频/IM聊天/直播等功能于一体的微直播项目.界面仿制抖音|火山小视频/陌陌直播,支持编译到多端(H5.小程序.Ap ...
- Vue3.0短视频+直播|vue3+vite2+vant3仿抖音界面|vue3.x小视频实例
基于vue3.0构建移动端仿抖音/快手短视频+直播实战项目Vue3-DouYin. 5G时代已来,短视频也越来越成为新一代年轻人的娱乐方式,在这个特殊之年,又将再一次成为新年俗! 基于vue3.x+v ...
- uniapp之uni-starter小程序多端研发框架搭建与项目实践
随着移动互联网的飞速发展,无数移动APP琳琅满目:在移动App的发展的基础上,衍生了小程序.轻应用技术,它随时可用,但又无需安装卸载.小程序是一种不需要下载安装即可使用的应用,它实现了应用" ...
- java实现微信小程序服务端(登录)
微信小程序如今被广泛使用,微信小程序按照微信官网的定义来说就是: 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 这就是微信小程序的魅力所在,有 ...
- 小程序 web 端实时运行工具
微信小程序 web 端实时运行工具 https://chemzqm.github.io/wept/
随机推荐
- 【Linux】2.2 Linux安装
安装 vm 和 Centos 学习 Linux 需要一个环境,我们需要创建一个虚拟机,然后在虚拟机上安装一个 Centos 系统来学习. 先安装 virtual machine ,vm12 再安装 L ...
- DevOps系列——Jenkins私服
DevOps基础设施较多,所以客官不要太着急,要有个"渐进明细"的过程,前面说了GitLab,这里再说下Jenkins,这俩算 是较为核心的基础组件,其他组件可选项较多,而这俩的地 ...
- Oracle PLSQL 存储过程无法进入单步调试
使用PLSQL工具调试存储过程的时候,不管你怎么设置断点,当你点击测试的时候就瞬间执行而过你无法进入单步调试 解决办法:
- ASP.NET MVC 视图中文乱码
以 Visual Studio 2017 Community 为例. 场景重现 某天新建了一个ASP.NET MVC项目,添加了一个视图文件写了个页面,页面内容中自然有中文, 字符集编码为<me ...
- android中大咖:TlistView
d的android中的Tlistview相当于cxGrid,其开发使用中的主咖地位至高无上. 可是如何高效使用快速实现的需求呢?需要的话补官方的教程 上图: GOODLUCK!
- 学习EXTJS6(10)面向对象的基础框架-2【统一的组件模型】很重要
用到ExtJS,UNIGUI是以ExtJS为基础的框架.因此掌握基础组件模型太重要了.确实就是让自己知道其所以然. Ext中所有可视组件都继承自Ext.Component. 1.Ext.Compone ...
- nodejs文本文件的读写
文本文件的换行符 方法一: var EOL = fileContents.indexOf("\r\n") >= 0 ? "\r\n" : "\n ...
- Spring RestTemplate使用方法总结
1. 引入依赖 首先,需要确认项目中是否直接或者间接引入过spring-web依赖,如果没有引入过,需要在pom.xml中添加以下代码引入依赖: <dependency> <grou ...
- Web前端入门第 39 问:细说 CSS position 定位布局
CSS 的定位属性 position 可以把元素从文档流中拧出来,让其显示在其他位置. 但凡元素定位属性加身,元素位置便不再受文档流控制,这时候什么 flex.grid 都不好使了,定位的元素已然跳出 ...
- php获取前一天,前一个月,前半年,前一年的时间戳
#获取前一小时strtotime("-1 hour") #获取前一天strtotime("-1 day") #获取前一周strtotime("-1 w ...