前言
这段时间捣鼓的一个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/
自定义组件Navbar/Tabbar/Vpopup
页面中顶部导航条、底部标签栏及所有的弹窗均是自定义组件实现的功能。
由于之前有过相关分享文章,这里不作过多的介绍。
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 来覆盖默认的配置。
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>
聊天功能模板
编辑框本来是使用input
或textarea
实现。可是考虑到文本框中只能插入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多端聊天实例