小工具知识网

当前位置: 首页 > 行业知识 > uniapp-vue3-wechat:基于uniapp+vue3仿微信app聊天实例(H5+小程序+App端)

行业知识

uniapp-vue3-wechat:基于uniapp+vue3仿微信app聊天实例(H5+小程序+App端)

2026-11-07 19:42:26 来源:互联网转载

uni-vue3-wchat:基于uni-app+vue3+pinia2高仿微信app聊天模板。

原创基于最新跨端技术uni-app+vue3.x+pinia2+vite4+uv-ui构建三端仿微信app界面聊天实例。实现编辑框多行消息/emoj混合、长按触摸式仿微信语音面板、图片/视频预览、红包/朋友圈等功能。支持编译到H5+小程序端+App端。

整个项目采用vue3 setup语法编码,支持编译到h5+小程序端+APP端。

使用技术

  • 编辑器:HbuilderX 4.0.8
  • 框架技术:Uniapp+Vue3+Pinia2+Vite4.x
  • 组件库:uni-ui+uv-ui
  • 弹窗组件:uv3-popup(uniapp+vue3多端自定义弹框组件)
  • 导航栏+菜单栏:uv3-navbar+uv3-tabbar组件
  • 本地缓存:pinia-plugin-unistorage
  • 编译支持:H5+小程序+APP端

    uniapp+vue3实现类似微信朋友圈功能。

    项目结构

    入口main.js配置

    /** * 入口文件 main.js*/import { createSSRApp } from 'vue'import App from './App'// 引入pinia状态管理import pinia from '@/pinia'export function createApp() {const app = createSSRApp(App)app.use(pinia)return {app,pinia}}

    App.vue配置

    采用 vue3 setup 语法开发。

        import { provide } from 'vue'    import { onLaunch, onShow, onHide, onPageNotFound } from '@dcloudio/uni-app'        onLaunch(() => {        console.log('App Launch')                uni.hideTabBar()        loadSystemInfo()    })        onShow(() => {        console.log('App Show')    })        onHide(() => {        console.log('App Hide')    })        onPageNotFound((e) => {        console.warn('Route Error:', `${e.path}`)    })        // 获取系统设备信息    const loadSystemInfo = () => {        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                })            }        })    }    /* #ifndef APP-NVUE */    @import 'static/fonts/iconfont.css';    /* #endif */    @import 'styles/reset.scss';    @import 'styles/layout.scss';

    uniapp+vue3自定义navbar+tabbar组件

            首页             Admin                            

    公共布局模板

    整体项目结构采用顶部导航区域+主体内容区+底部区域。

        export default {        /**         * 解决小程序class、id透传问题         * manifest.json中配置mergeVirtualHostAttributes: true, 在微信小程序平台不生效,组件外部传入的class没有挂到组件根节点上,在组件中增加options: { virtualHost: true }         * https://github.com/dcloudio/uni-ui/issues/753         */        options: { virtualHost: true }    }    const props = defineProps({        // 是否显示自定义tabbar        showTabBar: { type: [Boolean, String], default: false },    })                                                                                                                    

    uni-app+vue3微信九宫格图像组

        import { onMounted, ref, computed, watch, getCurrentInstance } from 'vue'        const props = defineProps({        // 图像组        avatar: { type: Array, default: null },    })        const instance = getCurrentInstance()        const uuid = computed(() => Math.floor(Math.random() * 10000))    const avatarPainterId = ref('canvasid' + uuid.value)        const createAvatar = () => {        const ctx = uni.createCanvasContext(avatarPainterId.value, instance)        // 计算图像在画布上的坐标        const avatarSize = 12        const gap = 2        for(let i = 0, len = props.avatar.length; i  {            // 输出临时图片            /* uni.canvasToTempFilePath({                canvasId: avatarPainterId.value,                success: (res) => {                    console.log(res.tempFilePath)                }            }) */        })    }        onMounted(() => {        createAvatar()    })        watch(() => props.avatar, () => {        createAvatar()    })                                                        .uv3__avatarPainter {background-color: #eee; border-radius: 5px; overflow: hidden; padding: 2px; height: 44px; width: 44px;}    .uv3__avatarPainter-canvas {height: 100%; width: 100%;}    .uv3__avatarOne {border-radius: 5px; height: 44px; width: 44px;}

    uni-app+vue3自定义弹出框组件

    v-model        当前组件是否显示title          标题(支持富文本p标签、自定义插槽内容)content        内容(支持富文本p标签、自定义插槽内容)type           弹窗类型(toast | footer | actionsheet | actionsheetPicker | android/ios)customStyle    自定义弹窗样式icon           toast图标(loading | success | fail | warn | info)shade          是否显示遮罩层shadeClose     是否点击遮罩时关闭弹窗opacity        遮罩层透明度round          是否显示圆角xclose         是否显示关闭图标xposition      关闭图标位置(left | right | top | bottom)xcolor         关闭图标颜色anim           弹窗动画(scaleIn | fadeIn | footer | fadeInUp | fadeInDown)position       弹出位置(top | right | bottom | left)follow         长按/右键弹窗(坐标点)time           弹窗自动关闭秒数(1、2、3)zIndex         弹窗层叠(默认202107)btns           弹窗按钮(参数:text|style|disabled|click)------------------------------------------## slot [插槽]------------------------------------------## emitopen        打开弹出层时触发(@open="xxx")close       关闭弹出层时触发(@close="xxx")

    uv3-popup支持函数式+组件式两种调用方式。

        import { onMounted, ref, computed, watch, nextTick, getCurrentInstance } from 'vue'        const props = defineProps({        ...    })    const emit = defineEmits([        'update:modelValue',        'open',        'close'    ])        const instance = getCurrentInstance()        const opts = ref({        ...props    })    const visible = ref(false)    const closeAnim = ref(false)    const stopTimer = ref(null)    const oIndex = ref(props.zIndex)    const uuid = computed(() => Math.floor(Math.random() * 10000))        const positionStyle = ref({ position: 'absolute', left: '-999px', top: '-999px' })        const toastIcon = {        ...    }        // 打开弹框    const open = (options) => {        if(visible.value) return        opts.value = Object.assign({}, props, options)        // console.log('-=-=混入参数:', opts.value)        visible.value = true                // nvue 的各组件在安卓端默认是透明的,如果不设置background-color,可能会导致出现重影的问题        // #ifdef APP-NVUE        if(opts.value.customStyle && !opts.value.customStyle['background'] && !opts.value.customStyle['background-color']) {            opts.value.customStyle['background'] = '#fff'        }        // #endif                let _index = ++index        oIndex.value = _index + parseInt(opts.value.zIndex)                emit('open')        typeof opts.value.onOpen === 'function' && opts.value.onOpen()                // 长按处理        if(opts.value.follow) {            nextTick(() => {                let winW = uni.getSystemInfoSync().windowWidth                let winH = uni.getSystemInfoSync().windowHeight                // console.log('坐标点信息:', opts.value.follow)                getDom(uuid.value).then(res => {                    // console.log('Dom尺寸信息:', res)                    if(!res) return                                        let pos = getPos(opts.value.follow[0], opts.value.follow[1], res.width+15, res.height+15, winW, winH)                    positionStyle.value.left = pos[0] + 'px'                    positionStyle.value.top = pos[1] + 'px'                })            })        }                if(opts.value.time) {            if(stopTimer.value) clearTimeout(stopTimer.value)            stopTimer.value = setTimeout(() => {                close()            }, parseInt(opts.value.time) * 1000)        }    }        // 关闭弹框    const close = () => {        if(!visible.value) return                closeAnim.value = true        setTimeout(() => {            visible.value = false            closeAnim.value = false                        emit('update:modelValue', false)            emit('close')            typeof opts.value.onClose === 'function' && opts.value.onClose()                        positionStyle.value.left = '-999px'            positionStyle.value.top = '-999px'                        stopTimer.value && clearTimeout(stopTimer.value)        }, 200)    }        // 点击遮罩层    const handleShadeClick = () => {        if(JSON.parse(opts.value.shadeClose)) {            close()        }    }        // 按钮事件    const handleBtnClick = (e, index) => {        let btn = opts.value.btns[index]        if(!btn?.disabled) {            console.log('按钮事件类型:', typeof btn.click)                        typeof btn.click === 'function' && btn.click(e)        }    }        // 获取dom宽高    const getDom = (id) => {        return new Promise((resolve, inject) => {            // uniapp vue3中 uni.createSelectorQuery().in(this) 会报错__route__未定义  https://ask.dcloud.net.cn/question/140192            uni.createSelectorQuery().in(instance).select('#uapopup-' + id).fields({                size: true,            }, data => {                resolve(data)            }).exec()        })    }        // 自适应坐标点    const getPos = (x, y, ow, oh, winW, winH) => {        let l = (x + ow) > winW ? x - ow : x        let t = (y + oh) > winH ? y - oh : y        return [l, t]    }        onMounted(() => {        if(props.modelValue) {            open()        }    })    watch(() => props.modelValue, (val) => {        // console.log(val)        if(val) {            open()        }else {            close()        }    })        defineExpose({        open,        close    })

    uni-app+vue3聊天功能

    目前该插件已经免费发布到插件市场,欢迎去下载使用。

    https://ext.dcloud.net.cn/plugin?id=13275

                                                                                                                                                                            未识别到文字                                        取消                发送原语音                                                                                                {{voiceTypeMap[voiceType]}}                    

    目前该项目已经同步到工房,如果有需要,欢迎自行去拍哈~

    https://gf.bilibili.com/item/detail/1105801011

    好了,综上就是uniapp+vue3跨端聊天实例的一些分享,希望大家能喜欢!

    最后附上几个最新实战项目

    • flutter3-winchat基于flutter3.x+bitsdojo_window桌面端仿微信

      https://blog.csdn.net/yanxinyun1990/article/details/136410049

    • flutter3_douyin基于flutter3.19仿抖音短视频/直播

      https://blog.csdn.net/yanxinyun1990/article/details/136996521

    • flutter3_macos基于flutter3.x+window_manager桌面端仿macOS系统

      https://blog.csdn.net/yanxinyun1990/article/details/137697164

上一篇:服务器上怎么安装svn服务器?

下一篇:怎么做坑产?