Nuxt-Chatroom 基于Nuxt.js+Vue.js仿微信|探探App界面聊天社交

运用nuxt.js+vue.js+vuex+vpopup+vant+webpack等技术架构开发的社交聊天室项目。实现了类Tinder翻牌左右滑动、消息发送|表情gif、图片|视频预览、消息记录下拉刷新、长按弹窗、红包|朋友圈等功能。

  

使用技术

  • 技术框架:nuxt.js+vue.js+vuex
  • UI组件库:vant: ^2.10.4
  • iconfont图标:阿里字体图标库
  • 弹窗组件:vpopup(基于vue封装自定义弹框)
  • 本地存储:cookie-universal-nuxt: ^2.1.4

项目结构

  

  

  

  

  

  

  

  

  

  

  

vue|nuxt自定义Navbar+Tabbar组件

顶部导航 / 底部标签栏是自定义组件实现。可以去参看这篇分享文章。

Vue|Nuxt自定义导航条/底部TabBar组件|vue仿咸鱼凸起Tab

vue|nuxt自定义弹出框组件

本来是考虑使用vant的弹出框功能,后来慎重考虑决定自己整一个弹框组件VPopup

大家有兴趣的话,可以去看看这篇分享文章。

Vue+Nuxt自定义弹窗|vue.js仿微信/ios弹层组件

vue|nuxt仿陌陌卡片滑动

翻一翻页面参考了探探/陌陌卡片拖拽堆叠效果。

如果对实现方式有兴趣的话,可以去看看下面这篇文章。

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

nuxt.config.js默认配置

nuxt的配置文件,更多详细配置参数大家可以去官网查看。

https://zh.nuxtjs.org/guide/configuration/

export default {
  // 端口配置(可选)
  server: {
    port: 3000,
    host: '192.168.101.69'
  },
  /*
  ** 页面头部meta信息配置
  */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1, user-scalable=no' },
      { hid: 'keywords', name: 'keywords', content: 'Vue.js | Nuxt.js | Nuxt仿微信'},
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      { rel: 'stylesheet', href: '/js/wcPop/skin/wcPop.css' },
    ],
    script: [
      { src: '/js/fontSize.js' },
      { src: '/js/wcPop/wcPop.js' },
    ]
  },
  /*
  ** 全局css配置
  */
  css: [
    '~/assets/css/reset.css',
    '~/assets/css/layout.css',
    '~/assets/fonts/iconfont.css',
  ],
  /*
  ** 全局插件列表
  */
  plugins: [
    '~/plugins/vue-global.js',
    // 通过这种方式引入本地js也可以(需设置ssr:false)
    // {src: '~/assets/js/fontSize.js', ssr: false}
  ],
  // ...
}

页面中SEO功能配置,既可以在nuxt.config.js中全局配置meta标签,也可以单独页面配置。

<script>
export default {
    // 用于配置页面的 meta 信息
    head() {
        return {
            title: '这里是标题信息 - 标题信息',
            meta: [
                {name:'keywords',hid: 'keywords',content: '关键字1 | 关键字2 | 关键字3'},
                {name:'description',hid:'description',content: '描述1 | 描述2 | 描述3'}
            ]
        }
    },
    // 自定义布局模板
    layout: 'xxx.vue',
    // 中间件验证
    middleware: 'auth',
    // 异步数据处理
    async asyncData({app, params, query, store}) {
        let uid = params.uid
        let cid = query.cid
        return {
            uid: uid,
            cid: cid,
        }
    },
    // ...
}
</script>

聊天模块

编辑框部分做成公共组件chatEditor.vue。运用了div的可编辑功能contenteditable来插入图文内容。

<template>
    <div
        ref="editor"
        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>
/**
 * @Desc     Vue编辑器实现
 * @Time     andy by 2020-10-06
 * @About    Q:282310962  wx:xy190310
 */
<script>
    export default {
        props: {
            value: { type: String, default: '' }
        },
        data () {
            return {
                editorText: this.value,
                isChange: true,

                // 记录光标最后位置
                lastCursor: null,
            }
        },
        watch: {
            value() {
                if(this.isChange) {
                    this.editorText = this.value
                }
            }
        },
        methods: {
            handleInput() {
                this.$emit('input', this.$el.innerHTML)

                this.lastCursor = this.getLastCursor()
            },
            
            // 点击编辑器
            handleClick() {
                this.$emit('clickFn')

                this.lastCursor = this.getLastCursor()
            },
            // 获取焦点
            handleFocus() {
                this.isChange = false
                this.$emit('focusFn')

                this.lastCursor = this.getLastCursor()
            },
            // 失去焦点
            handleBlur() {
                this.isChange = true
                this.$emit('blurFn')
            },

            // 获取光标最后位置
            getLastCursor() {
                let sel = window.getSelection()
                if(sel && sel.rangeCount > 0) {
                    return sel.getRangeAt(0)
                }
            },

            insertHtmlAtCursor(html) {
                let sel, range
                if(window.getSelection) {
                    // IE9及其它浏览器
                    sel = window.getSelection()

                    // *注意:判断最后光标位置
                    if(this.lastCursor) {
                        sel.removeAllRanges()
                        sel.addRange(this.lastCursor)
                    }

                    if(sel.getRangeAt && sel.rangeCount) {
                        range = sel.getRangeAt(0)
                        range.deleteContents()
                        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)
                }
            }
        }
    }
</script>

好了,基于Vue.js+Nuxt.js开发聊天室项目就分享到这里。希望对大家有所帮助!💪💪

最后附上一个项目实例

react+redux网页版聊天实例|react聊天室

 

Logo

前往低代码交流专区

更多推荐