在前面已经完成了侧边栏和路由的设计与实现。下面要玩完成项目的一个核心组件,对话的设计与实现。
需要完成的效果
本项目为可视化课程知识问答系统,核心功能就是通过对话获取想要的知识,并对具体的知识进行学习。因此对于对话组件,我们想要的效果是让对话组件始终悬停在页面的右侧,有两个角色,user和bot,可以发送信息,能够展示模型返回的信息,可以打开一个新的聊天。
同时,对话组件内的对话内容不随着路由、页面的改变而改变,因此需要引入vuex来保存相关数据。
在对话组件中进行交流时,会将用户输入的信息传给后端,后端返回时会返回可能与这个对话相关的,用户想要了解的知识点列表,以及模型的总体回复。
然后在对话的界面下方将根据用户可能想要了解的知识点展示出来。供用户点击选择具体查看哪个知识点的内容。
具体实现
页面UI的实现
将所有的对话信息保存在messages中。然后将messages中的对话内容展示在页面中。
<div class="chat-window">
<div
v-for="(message, index) in messages"
:key="index"
:class="['message-wrapper', message.sender]"
>
<div :class="['message', message.sender]">
<p>{{ message.text }}</p>
</div>
</div>
</div>
当后端接口返回我用户想要了解的知识点列表时,需要将这些知识点展示出来,并且可删除。在没有进行对话时将容器隐藏。
<div v-if="!ShowCard" class="chat-knowledge">
<card type="chart" cardCol>
<h4 class="card-category" style="margin: 0; padding-left: 7px; color: #9A9A9A; text-align:left;">你可能想要了解的知识</h4>
<div>
<span
v-for="knowledge in ProbKnowledge"
:key="knowledge"
class="knowledge-tag"
@click="handleClick(knowledge)"
>
{{ knowledge }}
<i
class="delete-icon"
@click.stop="removeKnowledge(knowledge)"
>x</i>
</span>
</div>
</card>
</div>
在组件的最下方实现input输入框,作为用户输入信息的方式,然后实现两个按钮,一个发送信息,一个创建新的对话。
<div class="chat-input">
<input
v-model="newMessage"
@keyup.enter="sendMessage"
placeholder="Type a message..."
style="size: small;"
/>
<button @click="sendMessage" style="size: small;">Send</button>
<button @click="clearMessage" style="size: small;">NewChat</button>
</div>
对话信息的保存
用户输入信息的保存
当用户输入信息后点击send按钮,触发函数sendMessage。
sendMessage() {
if (this.newMessage.trim() === "") return;
this.$store.commit('addMessage', { sender: 'user', text: this.newMessage });
this.$store.dispatch('simulateBotResponse', this.newMessage).then((data) => {
console.log(data)
this.ProbKnowledge = data.ProbKnowledge
})
this.newMessage = "";
},
通过$store.dispatch调用在store.js中的simulateBotResponse函数,并且将当前输入框中的newMessage传递给store.js中的addMessage
addMessage:
addMessage(state, message) {
state.messages.push(message);
},
后端返回信息的保存
simulateBotResponse:
async simulateBotResponse({ commit }, newMessage) {
const response = await api.post('/backMessage', newMessage);
console.log(response)
const ShowMessage = `This is a simulated response to your question: ${response.data.backmessage}`
commit('addMessage', { sender: 'bot', text: ShowMessage});
commit('setProbKnowledge', response.data.ProbKnowledge);
return response.data;
},
在simulateBotResponse将chat中的信息保存到state中的messages。并将后端返回的用户可能感兴趣的知识点列表保存到state中的ProbKnowledge。在chat.vue中将ProKnowledge显示在card里。
效果展示
UI效果
对话效果
当我们向VCRS-BOT提问:计算机网络7层模型有哪几部分时,会展示它的回复和用户可能感兴趣的知识点列表。