今天给大家分享的是vue3全家桶技术仿抖音系列之聊天界面功能实现。
项目整体配色为深黑色,顶部Navbar和底部Tabbar组件设置fixed固定沉浸式。让整个页面看起来融为一体。
一睹效果
其实聊天模块并不是这个项目的重点,为了功能不至于缺失,还是加上了。之前有分享一个vue3.0开发移动端聊天实例,大家感兴趣可以去看看。
Vue3.0+Vant3聊天室|vue3仿微信App聊天实例
消息/聊天目录结构
消息页模板
消息记录页整体分为导航栏+消息区+底部标签栏三部分。
其中下拉刷新和侧滑分别使用到了vant3组件库中的van-pull-refresh和van-swipe-cell组件。
<!-- //消息页模板 -->
<template>
<div class="bg-282a3a">
<!-- >>顶部 -->
<navbar :back="false" bgcolor="transparent" fixed>
...
</navbar>
<!-- >>主页面 -->
<div class="vui__scrollview scrolling flex1">
<van-pull-refresh v-model="isLoading" success-text="刷新成功" @refresh="onRefresh" style="overflow:auto;height:100%;">
<!-- 下拉提示 -->
<template #pulling>
<i class="iconfont icon-down"></i> 下拉刷新...
</template>
<!-- 释放提示 -->
<template #loosing>
<i class="iconfont icon-up"></i> 释放更新...
</template>
<div class="mb-20">
<div class="nt__uc-row vui-cell vui-cell--clickable" @click="isShowNewFriendPopup=true">
<div class="avatar" style="background:#00e077;"><i class="iconfont icon-peoples c-fff fs-42"></i></div>
<div class="lbl flex1 ml-20">粉丝</div>
<i class="iconfont icon-arrR c-9d9ea5 fs-24"></i>
</div>
<div class="nt__uc-row vui-cell vui-cell--clickable">
<div class="avatar" style="background:#fe2c55;"><i class="iconfont icon-qiehuan c-fff fs-42"></i></div>
<div class="lbl flex1 ml-20">互动消息</div>
<i class="iconfont icon-arrR c-9d9ea5 fs-24"></i>
</div>
</div>
<!-- ##消息记录列表 -->
<div class="vc__recordList">
<van-swipe-cell v-for="(item,index) in recordList" :key="index">
<div class="item vui-cell vui-cell--clickable" :class="{'topmost': item.topMost}" @click="goToChat" @contextmenu.prevent="handleContextPopup">
<div v-if="item.avatar" class="img"><img :src="item.avatar" /></div>
<div v-if="item.groups" class="img imgs"><img v-for="(item2,index2) in item.groups" :key="index2" :src="item2" /></div>
<div class="info flex1">
<h2 class="title">{{item.title}}</h2><p class="desc clamp1">{{item.subtit}}</p>
</div>
<label class="time flex-selft">{{item.time}}</label>
<em v-if="item.badge" class="vui__badge">{{item.badge}}</em>
<em v-if="item.dot" class="vui__badge-dot"></em>
</div>
<!-- 右侧按钮 -->
<template #right>
<div class="swipe__cell-btns flexbox">
<div class="vui__btn vui__btn-primary vui__btn--square" @click="handleTopMost">置顶</div>
<div class="vui__btn vui__btn-primary vui__btn--square" @click="handleDelete">删除</div>
</div>
</template>
</van-swipe-cell>
</div>
</van-pull-refresh>
</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>
聊天页模板
聊天页整体布局分为顶部导航+消息滚动区+底部编辑器三大模块。
<!-- //聊天模板 -->
<template>
<div class="bg-282a3a">
<!-- >>顶部 -->
<navbar bgcolor="linear-gradient(to right, #36384a, #36384a)" center fixed zIndex="1011">
<template #backIco><i class="iconfont icon-back"></i></template>
<template #title><em class="ff-gg">Vue3.0交流</em></template>
</navbar>
<!-- >>主页面 -->
<div class="vui__scrollview scrolling flex1" ref="scrollview" @click="handleMsgPanelClicked">
<!-- ...渲染消息记录 -->
<div class="vChatMsg-cnt">
...
</div>
</div>
<!-- >>底部功能面板区 -->
<div class="vui__footTool">
<!-- //输入框模块 -->
<div class="vui__editorPanel flexbox">
<div class="vui__editor flex1">
<editor ref="editorRef" v-model="editorText" @clickFn="handleEditorClick" @focusFn="handleEditorFocus" @blurFn="handleEditorBlur" />
</div>
<div class="vui__editor-btn" @click="handleEmojChooseView(0)"><i class="iconfont icon-face"></i></div>
<div class="vui__editor-btn" @click="handleEmojChooseView(1)"><i class="iconfont icon-tianjia"></i></div>
<div class="vui__editor-btn btn-submit" @click="handleSubmit"><i class="iconfont icon-up"></i></div>
</div>
<!-- //表情、选择模块 -->
<div v-show="isShowFootBar" class="vui__choosePanel">
<!-- 表情 -->
<div v-show="showFootBarIndex==0" class="vui__emotion">
<div class="vui__emotion-wrap flexbox flex-col">
<div class="vui__emotion-tabs flexbox flex-alignc">
<!-- <span class="item"><i class="iconfont icon-tianjia fs-36"></i></span> -->
<div class="flex1 flexbox">
<span v-for="(item,index) in emojList" :key="index" class="item" :class="{'on': item.selected}" @click="handleEmojTab(index)"><img :src="item.pathLabel" /></span>
</div>
<span class="item del" @click="handleDelClicked"><i class="iconfont icon-del2 fs-50"></i></span>
</div>
<div v-for="(item,index) in emojList" :key="index" class="vui__emotion-cells flex1" :class="{'cur': item.selected}">
<div :class="item.type == 'emoj' ? 'face__sm_list' : 'face__lg_list'">
<div class="face_list">
<div v-for="(item2,index2) in item.nodes" :key="index2" class="item">
<img v-if="item.type=='emoj'" :src="item2" class="emoj" @click="handleEmojClicked" />
<img v-else :src="item2" @click="handleGifClicked(item2)" />
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 选择区域 -->
<div v-show="showFootBarIndex==1" class="vui__choose vui__hairline-top">
<div class="vui__choose-cells">
<ul class="clearfix">
<li><div class="item"><span class="ico"><i class="iconfont icon-tupian"></i><input ref="pickImageRef" type="file" accept="image/*" @change="handleChooseImage" /></span><em>照片</em></div></li>
<li><div class="item"><span class="ico"><i class="iconfont icon-xiangji1"></i><input ref="pickVideoRef" type="file" accept="video/*" @change="handleChooseVideo" /></span><em>视频</em></div></li>
<li><div class="item" @click="isShowSendRedPacket=true"><span class="ico"><i class="iconfont icon-hongbao"></i></span><em>红包</em></div></li>
<li><div class="item" @click="handleShakeWin"><span class="ico"><i class="iconfont icon-qiehuan"></i></span><em>抖一抖</em></div></li>
<li><div class="item"><span class="ico"><i class="iconfont icon-fujin"></i></span><em>位置</em></div></li>
<li><div class="item"><span class="ico"><i class="iconfont icon-shoucang"></i></span><em>我的收藏</em></div></li>
<li><div class="item"><span class="ico"><i class="iconfont icon-mingpian2"></i></span><em>名片</em></div></li>
</ul>
</div>
</div>
</div>
</div>
<!-- ……网址预览模板 -->
<div v-if="isShowLinkView" class="nt__statePopup nt__lkView-wrap">
<navbar bgcolor="linear-gradient(to right, #36384a, #36384a)" center zIndex="2021">
<template #backIco><i class="iconfont icon-arrL"></i></template>
<template #title><div class="flexbox flex-alignc flex-justifyc">链接预览</div></template>
<template v-slot:right>
<div class="ml-30"><i class="iconfont icon-copylink"></i></div>
<div class="ml-30"><i class="iconfont icon-fenxiang"></i></div>
</template>
</navbar>
<div class="nt__statePopup-wrap">
<!-- //网址iframe -->
<iframe class="lkView" scrolling="auto" allowtransparency="true" frameBorder="0" :src="linkView"></iframe>
</div>
</div>
<!-- ……视频播放器模板 -->
<div v-if="isShowVideoPlayer" class="nt__statePopup nt__vplayer-wrap">
<navbar bgcolor="linear-gradient(to right, #36384a, #36384a)" center zIndex="2021">
<template #backIco><i class="iconfont icon-arrL"></i></template>
<template v-slot:right>
<div class="ml-30"><i class="iconfont icon-fenxiang1"></i></div>
<div class="ml-30"><i class="iconfont icon-vdots"></i></div>
</template>
</navbar>
<div class="nt__statePopup-wrap">
<!-- //视频video -->
<video class="vplayer" ref="playerRef" :src="videoList.videosrc" :poster="videoList.imgsrc" autoplay preload="auto" controls
x5-video-player-fullscreen="true"
webkit-playsinline="true"
x-webkit-airplay="true"
playsinline="true"
x5-playsinline
/>
</div>
</div>
<!-- ……红包弹窗模板(開) -->
<v3-popup v-model="isShowRedPacket" xclose xcolor="#ffe7bb" shadeClose="false">
...
</v3-popup>
<!-- ……发红包弹窗模板 -->
<v3-popup v-model="isShowSendRedPacket" xclose xposition="top" xcolor="#ffe7bb">
<redPacket />
</v3-popup>
<!-- ……群设置模板 -->
<v3-popup v-model="isShowSettingPopup" position="right" popupStyle="background:#36384a;">
<pageSetting />
</v3-popup>
</div>
</template>
其中网址链接查看、图片/视频预览、開红包等功能均是使用v3popup弹框组件来实现效果。
编辑器支持在光标处插入/删除表情,多行文本显示,动态链接检测等功能。
ok,基于vue3.x开发仿抖音聊天功能就分享到这里。希望大家喜欢哈![送心]