最近搞聊天室的人还挺多,正好自己也弄就总结自己遇到必不可少的一些功能,本篇文章主要为自己和看到我文章的人一种思路,希望大家不要把聊天室想的太复杂。
上图是我自己做的一个聊天室,类似微信的单聊群聊收藏等功能,根据自己现有需求,没有加朋友圈功能。
1、如何实现ctrl+回车换行,回车发送消息
如果你做的是 PC 端聊天室,免不了要实现换行功能,又有回车发送的便捷,我们该如何实现呢?
借助键盘的 keydown 事件,判断是否选中回车和 ctrl 键,然后添加对应的操作。具体实现代码如下:
<template>
<textarea
v-model="msg"
type="text"
class="lemon-editor"
@keydown="handleKeyCode($event)"
></textarea>
</template>
<script setup>
import { ref } from 'vue'
let msg = ref('')
function handleKeyCode(event) {
if (event.keyCode == 13) {
if (!event.ctrlKey) {
//发送消息网络请求
sendMsg(msg.value, 'TEXT')
event.preventDefault()
} else {
msg.value = msg.value + '\n'
}
}
}
</script>
2、如何发送表情
表情就像文字一样很简单的,只不过就是可能稍微麻烦一点,我们需要把表情当作文字一样复制过来,然后遍历展示就 ok 了。
<template>
<div >
<span v-for="item in emojilist " @click="choiceEmoj(item)">
{{item}}
</span>
</div>
</template>
<script setup>
import { ref } from 'vue'
let emojilist = ref([
'😁',
'😂',
'😃',
'😄',
'😅',
'😆',
'😉',
'😊',
'😋',
'😌',
'😍',
'😏',
'😒',
'😓',
'😔',
'😖',
'😘',
'😚',
'😜',
'😝',
'😞',
'😠',
'😡',
'😢',
'😣',
'😤',
'😥',
'😨',
'😩',
'😪',
'😫',
'😭',
'😰',
'😱',
'😲',
'😳',
'😵',
'😷',
'😸',
'😹',
'😺',
'😻',
'😼',
'😽',
'😾',
'😿',
'🙀',
'🙅',
'🙆',
'🙇',
'🙈',
'🙉',
'🙊',
'🙋',
'🙌',
'🙍',
'🙎',
'🙏',
])
let msg = ref('')
function choiceEmoj(item) {
console.log('表情', item)
msg.value += item
}
</script>
上述实例中是一些常见的表情,除此之外你可以加一些适合你项目的常用表情,假设你是卖水果的,你可以加各种水果,如:
let emojilist = ref([
'🍇','🍉','🍊','🍋','🍎','🍐','🍒',
'🍅','🍑','🍌','🍏','🥝','🍓','🥥'
])
授人之鱼不如授人以渔,大家可以在网站上进行复制,各种表情特殊符号等一应俱全,参考以下链接:
https://www.emojiall.com/zh-hans/categories
3、聊天记录怎么存?
聊天室最重要的就是聊天记录存在哪?人比较多的时候,聊天记录都存储在服务器显然是不太合适,但如果放在本地存储,就会出现换个设备的时候聊天记录丢了,无法找回,大多数都会存储在本地,该如何存储呢?
如上图,聊天分为左右两部分:
<1>左边部分是聊天列表,显示的好友信息,和最后一条聊天内容。
<2>某个好友的所有聊天内容。
chat_list_data 左边聊天列表该如何存储?
我们将好友 id 作为对象的主键,确保好友的唯一性,将好友和聊天内容作为对象内容,每次收到好友信息,或者发送信息时,就需要更新一下。
具体格式如下:
localStorage.setItem('chat_list_data',{
'1665542413547806722':{
userId:"1665542413547806722",
nickName: "l",
content: "11",
disturb: "N", //是否开启免打扰
num: 0, //未读消息数
personId: "1665554875533844482",
portrait: "https://baidu.com.cn/xzy-ti/2023/05/24/头像.jpg",
time: "2023/06/13 16:49:27"
top: "N",//是否置顶
userType: "normal",//好友状态
windowType: "SINGLE",//聊天类型 单聊、群聊
}
})
chat_data 右边聊天记录如何存储?
与上边原理相似,聊天记录是一个大的对象,好友的 userId 作为主键,对象内包含好友信息或群信息以及聊天内容列表,发送或收到内容时,我们只需要更新对应好友的聊天信息就可以。具体存储格式如下:
localStorage.setItem('chat_data',{
'1665542413547806722':{
fromInfo: {
nickName: "wj34561",
portrait: "https://www.baidu.com.cn/xzy-ti/2023/06/02/头像.png",
userId: "1666284903407722498",
userType: "normal",
},
groupInfo: {},
list:[
{
content: "{\"url\":\"http://www.xxx.com/170029A001.jpg\",\"name\":\"微信图片_20230504145640_20230607170029A001.jpg\",\"type\":\"jpg\"}"
msgId: "local",
msgType: "IMAGE",
nickName: "zhangshuansuo",
personId: "1665554875533844482",
portrait: "http://xx.com/20230327183917A173.jpg"
time: "2023/06/07 17:00:43",
type: 2, //消息类型 通知、自己发送的、接收到的、发送失败、成功
userId: "1665554875533844482",
windowType: "SINGLE",
}
]
}
})
其中的 content 需要根据发送的聊天内容进行区分,有图片、视频、文字、文件、位置等。以上大家可以作为一个参考,具体的存储格式还是需要根据自己项目去结合。
聊天记录删除、好友删除、添加新好友等操作,关联到聊天记录的都需要更新本地储存的聊天记录,具体的使用 pinia 或 vuex 可自行选择。
4、消息发送失败如何处理?
发送消息因为网络异常、好友删除、拉黑等因素,会导致消息发送失败,我们需要提示用户消息发送失败,可以进行重试或者提示信息。
给好友发送信息时,根据接口返回的结果,需要对不同类型的失败做对应处理。
不动手感觉没啥问题,做的时候才会知道一眼能看完的东西要做好多东西,希望大家也可以动手实践下,有问题欢迎评论区交流。