nuxt+vue聊天App实例|nuxt仿微信/Tinder卡片|朋友圈

4,079 阅读2分钟

前言

这段时间捣鼓的一个Nuxt.js项目实例NuxtChatRoom。
使用 nuxt.js+vue.js+vant+webpack 等技术开发的仿微信|探探界面社交聊天项目。
nuxt+vue仿微信App界面聊天室

基本实现了消息发送/表情emoj、下拉刷新消息、图片/视频预览、红包/朋友圈等功能。

技术实现

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

nuxt目录结构

快速了解Nuxt.js

基于 Vue.js 服务端渲染的_SSR_通用应用框架。Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。例如异步数据加载、中间件支持、布局支持等。

nuxt官网:nuxtjs.org/

nuxt中文网:zh.nuxtjs.org/

仓库地址:github.com/nuxt/nuxt.j…

自定义组件Navbar/Tabbar/Vpopup

页面中顶部导航条、底部标签栏及所有的弹窗均是自定义组件实现的功能。

由于之前有过相关分享文章,这里不作过多的介绍。

nuxt.js自定义导航栏+Tabbar标签栏

nuxt.js自定义弹框组件

nuxt仿探探卡牌式滑动

翻一翻页面模仿了探探左右堆叠卡片效果。页面布局分为 顶部导航、翻动区、底部标签栏 等三个部分。

前两天也有分享一篇文章,这里不多介绍了。

vue|nuxt仿探探卡片式左右拖拽滑动

nuxt布局及配置

nuxt.js中默认的布局模板在layouts/default.vue页面。通过<nuxt />来显示主体内容。

<template>
  <div class="nuxt__container flexbox flex-col">
    <header-bar />
    <div class="nuxt__scrollview scrolling flex1"><nuxt /></div>
    <tab-bar />
  </div>
</template>

nuxt.config.js配置文件

Nuxt.js 默认的配置涵盖了大部分使用情形,可通过 nuxt.config.js 来覆盖默认的配置。

zh.nuxtjs.org/guide/confi…

export default {
  // 端口配置(可选)
  server: {
    port: 3000,
    host: '192.168.122.100'
  },
  /*
  ** 页面头部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}
  ],
  // ...
}

nuxt.config.js中的meta是全局配置的,当然也可以单独页面配置。

这样让你的页面也具备SEO关键字和描述的功能。让搜索引擎快速检索到页面。

<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>

聊天功能模板

编辑框本来是使用inputtextarea实现。可是考虑到文本框中只能插入emoj字符,还要进行转义处理,就改为了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
 * @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(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>

好了,基于Nuxt.js/Vue开发聊天室项目就分享到这里。希望能喜欢哈!✍

最后附上一个Taro实例项目

taro+react聊天室|taro仿微信App多端聊天实例