測試代碼:https://github.com/robinfoxnan/vue-advanced-chat-test0?
控件源碼:https://github.com/advanced-chat/vue-advanced-chat?
先上個效果圖:
這個控件就是專門為聊天而設計的,但是也有一些不足:
1)有些引用的控件已經過期了,還有些內存泄漏;
2)示例的demo使用的google的firebase存儲,運行不起來;
文檔寫的太粗糙,所以折騰了一個上午,用內存數據測試了一下顯示效果。
要點如下:
1)聊天室(會話)需要設置各種屬性:
<template><vue-advanced-chatref="chat":current-user-id="currentUserId" // 當前用戶ID:rooms="JSON.stringify(rooms)" // 會話列表:messages="roomMessages" // 當前會話的消息列表:menu-actions="JSON.stringify(menuActions)" // 右側...的菜單// 消息有4個下拉菜單:message-selection-actions="JSON.stringify(messageSelectionActions)":loading-rooms="loadingRooms" // bool類型,是否正在加載會話列表:rooms-loaded="messagesLoaded" // bool類型,會話加載完畢,不在拉動加載:room-id="roomId" // 最初的會話ID:room-message="roomMessage" // 這個是個字符串,沒有發現用法:messages-loaded = "true" // 消息更新完以后,設置為true則不再動畫轉圈@add-room="addRoom($event.detail[0])" // 添加一個會話按鈕的回調@fetch-messages="fetchMessages($event.detail[0])" // 切換會話時候會觸發加載消息的回調@send-message="sendMessage($event.detail[0])" // 點擊發送按鈕時候觸發發送動作/>
</template>
2)會話的格式如下:
rooms: [{roomId: '1',roomName: '飛鳥 的聊天',avatar: icons[0],unreadCount: 1,lastUpdated: Date.now(),index: 1,lastMessage: {_id: '1',content: '在么?在么?',senderId: '1',username: '小花兒',timestamp: '10:20',saved: true,distributed: false,seen: true,new: true},users: [users["1"], users["2"]],typingUsers: [ '1' ]},{roomId: '2',roomName: '群聊',avatar: icons[1],unreadCount: 4,lastUpdated: Date.now(),index: 2,lastMessage: {_id: '2',content: '昨天我們做了一個測試……',senderId: '1',username: '飛鳥',timestamp: '10:20',saved: true,distributed: false,seen: true,new: true},users: [ users["1"], users["2"]],typingUsers: [ '2' ]}],
3)消息的格式如下:
const aMsg ={_id: '1',indexId: 1,content: '小花發送的測試消息',senderId: users["1"]._id,username: users["1"].username,avatar: users["1"].avatar,date: '13 November',timestamp: '10:20',system: false,saved: true,distributed: true,seen: true,deleted: false,failure: false,disableActions: false,disableReactions: false,};
4) 會話的消息的需要動態加載的:
// 點擊了聊天會話,會觸發這個回調函數,在這里加載消息fetchMessages({ room, options = {} }) {this.messagesLoaded = false;this.$emit('show-demo-options', false)if (options.reset) {//this.resetMessages()}console.log("選項:" +options);console.log("選中會話:" +room.roomId);this.roomMessages = roomMsgMap[room.roomId]this.messagesLoaded = true},
5) 發送消息動作:
帶有附件的其實要先上傳,上傳完畢后,將遠端的url賦值給url就認為是發送完畢了,不再顯示動畫了;否則一直轉圈,顯示發送中;
// 點擊了發送按鈕,則執行發送消息async sendMessage({ content, roomId, files, replyMessage }) {console.log("當前發送消息到對話:" + roomId );this.currentMsgSeq = this.currentMsgSeq + 1;const u = users[this.currentUserId];const message = {_id : this.currentMsgSeq.toString(),senderId: this.currentUserId,username: u.username,avatar: u.avatar,content: content,timestamp: formatDate(new Date()),date: '13 November',system: false,saved: true,distributed: true,seen: true,deleted: false,failure: false,disableActions: false,disableReactions: false,}if (files) {message.files = this.formattedFiles(files)console.log(files);}if (replyMessage) {message.replyMessage = {_id: replyMessage._id,content: replyMessage.content,sender_id: replyMessage.senderId}if (replyMessage.files) {message.replyMessage.files = replyMessage.files}}this.messagesLoaded = falseroomMsgMap[roomId].push(message);// console.log(roomMsgMap[roomId]);this.roomMessages = [...roomMsgMap[roomId]]// 注意,下面的用法不行,不刷新//this.roomMessages = roomMsgMap[roomId]console.log(this.roomMessages);this.messagesLoaded = true},formattedFiles(files) {const formattedFiles = []files.forEach(file => {const messageFile = {name: file.name,size: file.size,type: file.type,extension: file.extension || file.type,url: file.url || file.localUrl// 注意,這里設置了HTTP的圖片地址后,能正確加載,證明上傳完畢,上傳過程就停止了,不轉了//url :"https://img0.baidu.com/it/u=1746301175,572912059&fm=253&fmt=auto&app=120&f=JPEG?w=580&h=500"}if (file.audio) {messageFile.audio = truemessageFile.duration = file.duration}formattedFiles.push(messageFile)})return formattedFiles},
其他的我也沒有測試呢。
有興趣一起做即時通信的朋友可以私聊。