基于uni-app+vue3+uvui跨三端仿微信app聊天模板【h5+小程序+app】

763 阅读3分钟

经过两周爆肝研发,新版uniapp+vue3仿微信聊天app项目,正式完结啦~

未标题-2.png

uni-vue3-wechat使用最新跨端技术uni-app+vue3 setup编码开发。

未标题-4.png

实现仿微信长按说话语音面板、图片/视频预览、红包/朋友圈等功能。

p1.gif

p2.gif

p3.gif

使用技术

  • 编辑器:HbuilderX 4.75
  • 技术框架:uni-app+vue3+pinia2+vite5
  • 状态管理:pinia2
  • 组件库:uni-ui+uv-ui(uniapp+vue3组件库)
  • 弹框组件:uv3-popup(自定义uniapp+vue3多端弹框组件)
  • 自定义组件:uv3-navbar导航栏+uv3-tabbar菜单栏
  • 缓存技术:pinia-plugin-unistorage
  • 支持编译:h5+小程序+app端

未标题-6.png

项目结构目录

360截图20250810072343879.png

uniapp-vue3-wechat聊天项目支持运行h5+小程序+app端。已经同步到我的原创作品集。如果有需要的话,可以直接去拍哈,希望能对你有些帮助!

uni-app+vue3+pinia2+uv-ui跨三端仿微信app聊天模板

支持运行到h5端,pc页面以750px宽度显示页面布局结构。

image.png

image.png

image.png

App.vue配置文件

<script setup>
	import { provide } from 'vue'
	import { onLaunch, onShow, onHide, onPageNotFound } from '@dcloudio/uni-app'
	
	onLaunch(() => {
		console.log('App Launch')
		
		// 隐藏系统tabbar
		uni.hideTabBar({
			success: () => {},
			fail: () => {
				// 修复H5隐藏tabbar报错:Uncaught (in promise) {errMsg: 'hideTabBar:fail not TabBar page'}
				// #ifdef H5
				const uniTabbar = document.querySelector('.uni-tabbar-bottom')
				if (uniTabbar) {
					uniTabbar.style.display = 'none'
				}
				// #endif
			}
		})
		launchApp()
	})
	
	onShow(() => {
		console.log('App Show')
	})
	
	onHide(() => {
		console.log('App Hide')
	})
	
	onPageNotFound((e) => {
		console.warn('Route Error:', `${e.path}`)
	})
	
	// 获取系统设备信息
	const launchApp = () => {
		uni.getSystemInfo({
			success: (e) => {
				// 获取手机状态栏高度
				let statusBar = e.statusBarHeight
				let customBar
				
				// #ifndef MP
				customBar = statusBar + (e.platform == 'android' ? 50 : 45)
				// #endif
				
				// #ifdef MP-WEIXIN
				// 获取胶囊按钮的布局位置信息
				let menu = wx.getMenuButtonBoundingClientRect()
				// 导航栏高度 = 胶囊下距离 + 胶囊上距离 - 状态栏高度
				customBar = menu.bottom + menu.top - statusBar
				// #endif
				
				// #ifdef MP-ALIPAY
				customBar = statusBar + e.titleBarHeight
				// #endif
				
				// 由于globalData在vue3 setup存在兼容性问题,改为provide/inject替代
				provide('globalData', {
					statusBarH: statusBar,
					customBarH: customBar,
					screenWidth: e.screenWidth,
					screenHeight: e.screenHeight,
					platform: e.platform
				})
			}
		})
	}
</script>

<style>
	/* #ifndef APP-NVUE */
	@import 'static/fonts/iconfont.css';
	/* #endif */
	/* 隐藏系统Tabbar */
	.uni-app--showtabbar .uni-tabbar-bottom {display: none;}
</style>
<style lang="scss">
	@import 'styles/reset.scss';
	@import 'styles/layout.scss';
</style>

通用布局模板

image.png

项目分为顶部导航条+内容区域+底部操作栏三个大模块。

1d03870103142fd96dedf45512f5b03e_1289798-20250811104505550-907356319.png

<!-- #ifdef MP-WEIXIN -->
<script>
    export default {
        /**
         * 解决小程序class、id透传问题
         * manifest.json中配置mergeVirtualHostAttributes: true, 在微信小程序平台不生效,组件外部传入的class没有挂到组件根节点上
         * https://github.com/dcloudio/uni-ui/issues/753
         */
        options: { virtualHost: true }
    }
</script>
<!-- #endif -->

<script setup>
    const props = defineProps({
        // 是否显示自定义tabbar
        showTabBar: { type: [Boolean, String], default: false },
    })
</script>

<template>
    <view class="uv3__container flexbox flex-col flex1">
        <!-- 顶部插槽 -->
        <slot name="header" />
        
        <!-- 内容区 -->
        <view class="uv3__scrollview flex1">
            <slot />
        </view>
        
        <!-- 底部插槽 -->
        <slot name="footer" />
        
        <!-- tabbar栏 -->
        <uv3-tabbar v-if="showTabBar" hideTabBar fixed />
    </view>
</template>

uniapp+vue3自定义导航条+底部tabbar

image.png

自定义导航栏和tabbar组件在components目录下。

1a3ab81c57215ae7acce062c66df6dd8_1289798-20250811105235627-259330578.png

<uv3-navbar :back="true" title="标题" bgcolor="#07c160" color="#fff" fixed zIndex="2025" />

支持自定义插槽。

<uv3-navbar custom bgcolor="linear-gradient(to right, #07c160, #0000ff)" color="#fff" center transparent z-index="2024">
    <template #back>自定义左侧返回按钮</template>
    <template #backText>自定义返回文字</template>
    <template #title>
        自定义标题
    </template>
    <template #right>
        自定义右侧
    </template>
</uv3-navbar>

bdad82cdcb69a54b9f3bc00ffcf3752f_1289798-20250811105733746-1662307678.png

uniapp+vue3聊天模板

b7d15d8035a24da4d4f5a496141843c4_1289798-20250811110148437-1901116720.png

b45ed63afc09c06854f2fcfcb6450cc7_1289798-20250811110303712-1861912022.png

聊天编辑框采用自定义组件实现功能,属于增强版input编辑框。

5ff58801d34384fa3d262f956707735f_1289798-20250811110402424-546715397.png

p5-2.gif

<view class="uv3__chattoolbar" :style="{'padding-bottom': fixPaddingBottom}">
	<!-- 输入框 -->
	<view class="uv3__chattoolbar-editor flexbox">
		<view class="btn" @click="handleVoice"><text class="uv3-icon" :class="voiceBtnEnable ? 'uv3-icon-voice' : 'uv3-icon-keyboard'"></text></view>
		<view class="editor flex1">
			<template v-if="voiceBtnEnable">
				<uv3-input
					v-model="editorValue"
					type="textarea"
					:autosize="{maxRows: 6}"
					:autofocus="autofocus"
					:cursor="editorLastCursor"
					clearable
					style="width: 100%;"
					@input="handleEditorInput"
					@focus="handleEditorFocus"
					@blur="handleEditorBlur"
				/>
			</template>
			<template v-else>
				<view class="uv3__voice-handle flexbox" @touchstart.prevent="handleTouchStart" @touchmove="handleTouchUpdate" @touchend="handleTouchEnd">{{voiceTypeMap[voiceType]}}</view>
			</template>
		</view>
		<view class="btn" @click="handleEmojPlusView(0)" @mousedown.prevent><text class="uv3-icon uv3-icon-face"></text></view>
		<view class="btn" @click="handleEmojPlusView(1)"><text class="uv3-icon uv3-icon-plus"></text></view>
		<view class="btn" @click="handleSend" @mousedown.prevent><view class="send flexbox"><uni-icons type="arrow-up" color="#fff" size="16"></uni-icons></view></view>
	</view>
	
	<!-- 操作栏 -->
	<view v-show="showToolbar" class="uv3__chattoolbar-operate">
		<!-- 表情 -->
		<view v-show="toolbarIndex == 0" class="uv3__chattoolbar-emotion flexbox flex-col">
			<view class="uv3__emotion-tabs flexbox flex-alignc">
				<view v-for="(item, index) in emojList" :key="index" class="item" :class="{'on': item.selected}" @click="handleEmojTab(index)">
					<text v-if="item.type=='emoj'" class="emoj uv3-icon uv3-icon-face"></text>
					<image v-else :src="item.pathLabel" />
				</view>
			</view>
			<view v-for="(item, index) in emojList" :key="index" class="uv3__emotion-cells flex1" :class="{'active': item.selected}">
				<view class="flexbox" :class="item.type == 'emoj' ? 'emojwrap' : 'gifwrap'">
					<view v-for="(emoj, key) in item.nodes" :key="key" class="cells flexbox">
						<view class="item">
							<text v-if="item.type=='emoj'" class="emoj" @click="handleEmojClick(emoj)">{{emoj}}</text>
							<image v-else :src="emoj" class="gif" @click="handleGifClick(emoj)" />
						</view>
					</view>
				</view>
			</view>
		</view>
		<!-- 操作栏 -->
		<view v-show="toolbarIndex == 1" class="uv3__chattoolbar-pluschoose flexbox">
			<view v-for="(item, index) in chooseList" :key="index" class="uv3__plusbtns-cells" @click="handlePlusAction(item)">
				<view class="icon flexbox"><image :src="item.icon" /></view>
				<view class="label">{{item.label}}</view>
			</view>
		</view>
	</view>
</view>

以上就是uni-app+vue3实战搭建跨端仿微信app聊天项目的一些分享知识。

基于flutter3.32+window_manager仿macOS/Wins风格桌面os系统

flutter3.27+bitsdojo_window电脑端仿微信Exe应用

基于uniapp+vue3+uvue短视频+聊天+直播app系统

基于uniapp+vue3+deepseek+markdown搭建app版流式输出AI模板

vue3.5+deepseek+arco+markdown搭建web版流式输出AI模板

Flutter3.x深度融合短视频+直播+聊天app实例

自研tauri2.0+vite6.x+vue3+rust+arco-design桌面版os管理系统Tauri2-ViteOS

自研tauri2.0+vite5+vue3+element-plus电脑版exe聊天系统Vue3-Tauri2Chat

原创electron31+vite5.x+elementPlus桌面端后台管理系统

Vite5-Electron-Wechat聊天实例|electron31+vue3客户端聊天EXE