一、基本結構
<template>
<div class="chat-room">
<div class="chat-history">
<div v-for="message in messages" class="chat-message" :class="{ 'my-message': message.isMyMessage }">
<div class="message-details">
<p class="username">{{ message.username }}</p>
<p class="time">{{ message.time }}</p>
</div>
<p class="message-body">{{ message.body }}</p>
</div>
</div>
<div class="chat-input">
<input type="text" placeholder="Type a message" v-model="newMessage" @keyup.enter="sendMessage">
<button class="send-message-btn" @click="sendMessage">發送</button>
</div>
</div>
</template>
以上是一個簡單的聊天對話框組件的基本結構,其中包括兩部分:chat-history和chat-input。chat-history是展示聊天記錄的部分,chat-input是用戶輸入聊天內容的部分。
在組件內部,我們需要定義一個序列,用來保存聊天記錄信息,即messages。messages數組中的每一項應該包含三個屬性:username、time和body。當用戶發送聊天信息時,我們應該在input框中以v-model的形式綁定到一個叫做newMessage的數據上,同時通過keyup.enter事件監聽用戶回車輸入,並執行sendMessage方法。
以下是組件內data以及sendMessage方法的基本結構:
<script>
export default {
data() {
return {
messages: [], // 聊天記錄序列
newMessage: '' // 用戶輸入的聊天信息
}
},
methods: {
sendMessage() {
// 創建消息對象
let newMsg = {
username: '某某用戶',
time: new Date().toLocaleString(), // 獲取當前時間並格式化
body: this.newMessage,
isMyMessage: true // 標記為本人發出的信息
};
// 將消息添加到消息序列中去
this.messages.push(newMsg);
// 將input框的值清空
this.newMessage = '';
// 滾動到最底部
this.$nextTick(() => {
this.$refs.chatHistory.scrollTop = parseInt(window.getComputedStyle(this.$refs.chatHistory).height);
});
}
}
};
</script>
在sendMessage方法中,我們在將用戶發送的聊天記錄push到messages序列中之後,還需要執行輸入框清空、機器回復、窗口滑動到最下方的任務。
二、樣式美化
.chat-room {
display: flex;
flex-direction: column;
justify-content: flex-end;
height: 400px;
width: 400px;
border: 5px solid #C1C1C1;
border-radius: 5px;
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
.chat-history {
flex: 1;
padding: 20px 20px 0;
margin-bottom: 10px;
overflow-y: scroll;
word-break: break-all; /* 長文本斷行 */
}
.chat-message {
display: flex;
}
.message-details {
margin-right: 10px;
font-size: 14px;
color: #999;
}
.my-message .message-details {
margin-left: 10px;
margin-right: 0;
text-align: right;
}
.message-body {
background-color: #EEE;
padding: 10px 15px;
border-radius: 10px;
max-width: 75%;
}
.my-message .message-body {
background-color: #4CAF50;
color: white;
margin-right: 10px;
}
.chat-input {
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid #C1C1C1;
padding: 10px 20px;
}
.chat-input input[type="text"] {
border: none;
outline: none;
font-size: 14px;
padding: 8px;
flex: 1;
margin-right: 10px;
background-color: #F0F0F0;
border-radius: 3px;
::placeholder {
color: #AAA;
}
}
.chat-input .send-message-btn {
border: none;
outline: none;
background-color: #008CBA;
color: white;
padding: 8px;
border-radius: 3px;
cursor: pointer;
transition: all ease-in-out 0.2s;
&:hover {
background-color: #005F6B;
}
}
除了基本的布局之外,我們還需要通過CSS樣式來進行美化,讓聊天對話框看起來更具有交互性。
樣式段落中定義了對話框的基本樣式以及聊天記錄、用戶發送內容的美化樣式。需要注意的是,為了更好的用戶體驗,我們需要將聊天記錄容器chat-history設置為自動滾動,確保用戶一直能看到最新的消息內容,同時也避免了消息被屏幕遮蓋的問題。
三、小技巧
1、消息的自動滾動
this.$nextTick(() => {
this.$refs.chatHistory.scrollTop = parseInt(window.getComputedStyle(this.$refs.chatHistory).height);
});
在sendMessage方法中,我們需要將窗口滾動到最底部,以便用戶能夠看到最新的聊天記錄。由於Vue動態渲染的特殊性,直接使用原生JS獲取元素height值來進行scrollTop的賦值是行不通的,因為在代碼尚未渲染完成時,我們得到的height是初始值0。所以我們需要以異步代碼的形式,通過Vue的$nextTick方法幫助我們等待元素渲染完成後再進行scroll操作,以獲取正確的height值。
2、機器人自動回復
sendMessage() {
// ...
// 機器人自動回復
setTimeout(() => {
let replyMsg = {
username: '機器人小隨',
time: new Date().toLocaleString(),
body: '您的消息已收到,稍後將有專人為您服務。',
isMyMessage: false
};
this.messages.push(replyMsg);
this.$nextTick(() => {
this.$refs.chatHistory.scrollTop = parseInt(window.getComputedStyle(this.$refs.chatHistory).height);
});
}, 1000);
}
在用戶發送內容之後,我們通常需要在服務器、數據庫等後端系統處進行處理。但是在前端展示時,我們可以通過異步代碼來使機器人自動回復用戶的消息。在sendMessage方法中,我們需要使用setTimeout進行延時操作,並創建一個replyMsg對象,模擬機器人的回復消息,然後將其push到messages序列中。最後,我們再次執行窗口滑動到最下方的操作,確保用戶能夠看到機器人回復的內容。
3、監聽滾動事件
mounted() {
this.$refs.chatHistory.addEventListener('scroll', this.handleScroll)
},
destroyed() {
this.$refs.chatHistory.removeEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll() {
let scrollTop = this.$refs.chatHistory.scrollTop;
if (scrollTop === 0) {
// 執行加載更多的操作
}
}
}
在一些場景下,我們可能需要用戶滾動到聊天記錄的頂部時,自動加載更多的歷史聊天記錄。Vue提供了一種事件監聽的方式,讓我們可以輕鬆地實現該功能。在聊天對話框被掛載到DOM之後,我們可以通過addEventListener監聽chatHistory元素的scroll事件。當scroll事件被觸發時,我們可以通過判斷scrollTop的大小來判斷用戶是否滑動到了頂部。如果scrollTop為0,代表用戶已經滑動到頂部了,此時可以執行加載更多的操作。需要注意,Vue中,在組件銷毀時需要在destroyed生命周期中移除scroll事件的監聽。
4、處理超長聊天記錄的斷行
.chat-history {
// ...
word-break: break-all;
}
在用戶發送的聊天記錄中,如果有長時間的文本、鏈接等內容,我們需要進行處理,以保證UI的美觀性和閱讀性。在樣式段落中,我們使用CSS的word-break屬性進行處理:當聊天記錄的文本元素寬度超過父元素寬度時,自動斷行,並將一些單詞或連接符號拆分到下一行。這樣能夠有效解決聊天記錄文本溢出、遮蓋的問題,提高聊天室的可用性。
原創文章,作者:DCKI,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/149798.html