vue 模拟 chatgpt 聊天效果:js 实现逐字显示、延时函数模拟对话
模拟 chatgpt 聊天功能,展示对话效果。其中比较有意义的技术点是:js 实现逐字显示、延时函数,同步遍历。
<template>
<div class="chat-gpt">
<div id="chat-dialog" class="chat-dialog" ref="chatDialogRef">
<div id="chat-list" class="chat-list" ref="chatListRef">
<div v-for="(item, index) in chatList" :key="index">
<img
v-if="item.status && index % 2 == 0"
src="../../public/img/speak1.gif"
alt=""
/>
<div :class="index % 2 == 0 ? 'odd' : 'even'">{{ item.content }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
textCount: 0,
timer: null,
chatBaseList: [
"以今日5辆满电无人车,运输5小时能运完50吨货物的标准,已知每辆无人车运输1小时耗电10%,运输效率是多少,每辆无人车耗电多少?花费多长时间?",
"运输效率:50吨/5小时=10顿/小时,每辆无人车耗电:10%×5小时=50%,需花费5小时。",
"以现有运输效率前提下,再增加5辆无人运输车,完成共计150吨物资的运输任务,整体效率会提高到多少?每辆无人车耗电又是多少?共花费多长时间?",
"增加到10辆无人车,完成共计150吨物资运输任务,整体效率会提高到15顿/小时,每辆无人车耗电百分比是15%。运完150吨的话,总共要耗用1.5小时。",
"我来想想是否确认执行此调配操作?",
"您好,请您慎重考虑。我们将根据您的确认来决定是否执行此调配操作。",
"是"
],
chatList: []
};
},
mounted() {
this.initGPT();
},
methods: {
// 延时函数
sleep(delaytime = 10000) {
return new Promise(resolve => setTimeout(resolve, delaytime));
},
// 同步遍历,自定义延时时间
async delayDo(
iterList,
callback = data => console.log(`数据:${data}`),
delaytimeList
) {
let len = iterList.length;
for (let i = 0; i < len; i++) {
callback(iterList[i], i);
await this.sleep(delaytimeList[i]);
}
},
// 逐字显示内容
getChatContent(text, index) {
this.timer = setInterval(() => {
this.textCount++;
if (this.textCount == text.length + 1) {
this.textCount = 0;
this.chatList.splice(index, 1, { content: text, status: false });
clearInterval(this.timer);
return;
}
// 取字符串子串
let nowStr = text.substring(0, this.textCount);
this.chatList.splice(index, 1, { content: nowStr, status: true });
}, 200);
},
// 点击开始聊天
initGPT() {
// const delaytimeList = [11000, 8000, 6000, 15000, 4000];
const delaytimeList = [16000, 11000, 16000, 16000, 5000, 7000];
this.delayDo(
this.chatBaseList,
(item, i) => {
this.getChatContent(item, i);
},
delaytimeList
);
}
}
};
</script>
<style lang="scss" scoped>
.chat-gpt {
width: 33rem;
height: 43rem;
.chat-dialog {
position: relative;
height: 43rem;
background: 0/33rem url("../../public/img/chat-bg.png") no-repeat;
overflow: hidden;
.close-icon {
position: absolute;
top: 1rem;
right: 1rem;
width: 3.4rem;
height: 3.4rem;
img {
width: 100%;
height: 100%;
}
}
.chat-list {
display: flex;
flex-direction: column;
width: 90%;
margin: 0 auto;
margin-top: 2rem;
overflow: auto;
>div {
display: flex;
margin-top: 1rem;
>div {
max-width: 19rem;
padding: 0.6rem;
opacity: 0.8;
font-size: 0.9rem;
font-family: FZLanTingHei-L-GBK;
font-weight: 400;
color: #c5e7ff;
text-align: start;
}
.odd {
align-self: flex-start;
background: #435e6f;
border-radius: 0px 16px 16px 16px;
}
.even {
align-self: flex-end;
background: #31b8c8;
border-radius: 16px 0px 16px 16px;
}
img {
width: 2rem;
height: 2rem;
margin-right: 1rem;
}
}
>div:nth-of-type(odd) {
align-self: flex-start;
}
>div:nth-of-type(even) {
align-self: flex-end;
}
}
}
.chat-tips {
display: flex;
height: 5.82rem;
margin-top: 1rem;
.gpt-icon {
height: 100%;
img {
height: 100%;
}
}
}
}
</style>
chatgpt 聊天效果