我的项目介绍

Vue3Chatroom 一个基于vue3.0+vant3.x搭建开发的仿微信手机端app界面聊天实例。实现了发送音讯/动图gif、图片/视频预览、网址链接查看、下拉刷新、红包/朋友圈等性能。

技术栈

  • 编码+技术:Vscode + Vue3.x/Vuex4.x/Vue-Router4
  • UI组件库:Vant3.x (有赞挪动端vue3.0组件库)
  • 弹层组件:V3Popup(基于vue3自定义弹层组件)
  • iconfont图标:阿里字体图标库
  • 自定义顶部Navbar栏+底部Tabbar


















我的项目构造

vue3.0自定义navbar+tabbar组件

我的项目中顶部导航条和底部tab栏均是自定义组件实现。

大家如果对其实现形式感兴趣,能够去看看vue2中实现形式。
vue.js实现自定义顶部导航+底部tab切换

vue3.0自定义挪动端弹框

我的项目中各种弹框场景都是基于vue3开发的自定义弹框组件实现的。

v3popup一款汇合多种弹框动画及类型的Vue3多功能mobile弹框组件。
vue3.0系列之自定义mobile弹框组件|vue3挪动端对话框

vue.config.js根本配置

vue3中 vue.config.js 根底配置信息。

const path = require('path')module.exports = {    // 根本门路    // publicPath: '/',    // 输入文件目录    // outputDir: 'dist',    // assetsDir: '',    // 环境配置    devServer: {        // host: 'localhost',        // port: 8080,        // 是否开启https        https: false,        // 编译完是否关上网页        open: false,                // 代理配置        // proxy: {        //     '^/api': {        //         target: '<url>',        //         ws: true,        //         changeOrigin: true        //     },        //     '^/foo': {        //         target: '<other_url>'        //     }        // }    },    // webpack配置    chainWebpack: config => {        // 配置门路别名        config.resolve.alias            .set('@', path.join(__dirname, 'src'))            .set('@assets', path.join(__dirname, 'src/assets'))            .set('@components', path.join(__dirname, 'src/components'))            .set('@views', path.join(__dirname, 'src/views'))    }}

vue3.0主页面main.js

引入一些公共组件/款式,路由、状态治理等文件。

import { createApp } from 'vue'import App from './App.vue'// 引入vuex和路由配置import store from './store'import router from './router'// 引入jsimport '@assets/js/fontSize'// 引入公共组件import Plugins from './plugins'const app = createApp(App)app.use(store)app.use(router)app.use(Plugins)app.mount('#app')

vue3.0表单验证及登录拦挡

vue3中应用 getCurrentInstance 获取以后上下文,用来操作store或router。

<script>import { reactive, inject, getCurrentInstance } from 'vue'export default {    components: {},    setup() {        const { ctx } = getCurrentInstance()        const v3popup = inject('v3popup')        const utils = inject('utils')        const formObj = reactive({})        // ...        const handleSubmit = () => {            if(!formObj.tel){                Snackbar('手机号不能为空!')            }else if(!utils.checkTel(formObj.tel)){                Snackbar('手机号格局不正确!')            }else if(!formObj.pwd){                Snackbar('明码不能为空!')            }else{                ctx.$store.commit('SET_TOKEN', utils.setToken());                ctx.$store.commit('SET_USER', formObj.tel);                // ...            }        }        return {            formObj,            handleSubmit        }    }}</script>

vue3中配置 全局钩子 实现拦挡登录状态。

router.beforeEach((to, from, next) => {    const token = store.state.token    // 判断以后路由地址是否须要登录权限    if(to.meta.requireAuth) {        if(token) {            next()        }else {            // 未登录受权            V3Popup({                content: '还未登录受权!', position: 'top', popupStyle: 'background:#fa5151;color:#fff;', time: 2,                onEnd: () => {                    next({ path: '/login' })                }            })        }    }else {        next()    }})

vue3.0聊天模块

我的项目中聊天编辑器局部抽离公共组件Editor,基于div可编辑contenteditable属性实现性能。

/** * @Desc     Vue3.0实现文字+emoj表情混排 * @Time     andy by 2021-01 * @About    Q:282310962  wx:xy190310 */<script>    import { ref, reactive, toRefs, watch, nextTick } from 'vue'    export default {        props: {            modelValue: { type: String, default: '' }        },        setup(props, { emit }) {            const editorRef = ref(null)            const data = reactive({                editorText: props.modelValue,                isChange: true,                lastCursor: null,            })            // ...            // 获取光标最初地位            const getLastCursor = () => {                let sel = window.getSelection()                if(sel && sel.rangeCount > 0) {                    return sel.getRangeAt(0)                }            }            // 光标处插入内容 @param html 须要插入的内容            const insertHtmlAtCursor = (html) => {                let sel, range                if(window.getSelection) {                    // IE9及其它浏览器                    sel = window.getSelection()                    // ##留神:判断最初光标地位                    if(data.lastCursor) {                        sel.removeAllRanges()                        sel.addRange(data.lastCursor)                    }                    if(sel.getRangeAt && sel.rangeCount) {                        range = sel.getRangeAt(0)                        let el = document.createElement('div')                        el.appendChild(html)                        var frag = document.createDocumentFragment(), node, lastNode                        while ((node = el.firstChild)) {                            lastNode = frag.appendChild(node)                        }                        range.insertNode(frag)                        if(lastNode) {                            range = range.cloneRange()                            range.setStartAfter(lastNode)                            range.collapse(true)                            sel.removeAllRanges()                            sel.addRange(range)                        }                    }                } else if(document.selection && document.selection.type != 'Control') {                    // IE < 9                    document.selection.createRange().pasteHTML(html)                }                // ...            }            return {                ...toRefs(data),                editorRef,                handleInput,                handleDel,                // ...            }        }    }</script>

行了,基于vue3实现聊天我的项目就介绍到这里。心愿以上分享对大家有些帮忙!

最初附上一个uniapp实例我的项目
uniapp+vue仿抖音小视频|uni-app直播实例