vue3.0+vuex+vant3.x聊天实战|vue3仿微信聊天+朋友圈

xiaoyan2015 · 2021-01-12 00:15:20 · 4106 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2021-01-12 00:15:20 的主题,其中的信息可能已经有所发展或是发生改变。

项目介绍

Vue3.x的推出让vue.js在2021年又再一次成为开发者受青睐的前端框架。

Vue3WChat聊天项目 使用vue3.x+@vue/cli+vuex+vue-router+vant-ui3.x等技术架构的移动端仿微信聊天实例。支持发送消息/emoj图、图片/视频查看、网址预览、红包/朋友圈等功能。

vue3.x+vant-ui 实现仿微信朋友圈功能。

框架技术

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

项目结构

vue3.0自定义全局弹层

大家看到的项目中所有弹框场景,都是使用vue3自定义组件实现。

v3popup 一款集合了众多弹框类型的vue3手机端自定义弹框组件。

vue3.x自定义组件系列:vue3移动端弹框组件v3popup

vue3.0配置文件

使用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主入口页面进行一些配置,使得引入公共组件/样式、路由和vuex。

import { createApp } from 'vue'
import App from './App.vue'

// 引入vuex和路由配置
import store from './store'
import router from './router'

// 引入js
import '@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.x中没有this,只能使用getCurrentInstance来获取上下文操作。

<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.0聊天部分

聊天编辑框部分封装了一个公共组件Editor,使用div可编辑contenteditable属性实现功能。

<template>
    <div
        ref="editorRef"
        class="editor"
        contentEditable="true"
        v-html="editorText"
        @click="handleClick"
        @input="handleInput"
        @focus="handleFocus"
        @blur="handleBlur"
        style="user-select:text;-webkit-user-select:text;">
    </div>
</template>

vue3获取光标位置,在光标处插入emoj表情。

/**
 * @Desc     Vue3.0实现文字+emoj表情混排
 * <a href="/user/Time" title="@Time">@Time</a>     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>

ok,基于vue3开发仿制微信聊天界面实例暂时就分享到这里。后续还会分享一些vue3实战开发。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4106 次点击  
加入收藏 微博
3 回复  |  直到 2021-01-12 11:29:32
focusonline
focusonline · #1 · 4年之前

好新的技术啊. 不过不是听说vue3已经使用ts作为开发语言了吗?

xiaoyan2015
xiaoyan2015 · #2 · 4年之前
focusonlinefocusonline #1 回复

好新的技术啊. 不过不是听说vue3已经使用ts作为开发语言了吗?

是的,vue3源码是基于ts编写,如果比较熟悉ts,也可以使用ts来开发项目。

focusonline
focusonline · #3 · 4年之前
xiaoyan2015xiaoyan2015 #2 回复

#1楼 @focusonline 是的,vue3源码是基于ts编写,如果比较熟悉ts,也可以使用ts来开发项目。

嗯, ts写起来很像java了. 很有意思

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传