前端实现逐字展示效果
杨了仰头 2024-07-28 12:03:01 阅读 54
AI🔥了,发现了一个有点意思的东西,就是逐字展示,以下就是它的实现方式
vue3+ts实现
一、<code>setTimeout
<template>
<div>
<button @click="startDisplayStr">逐字展示</button><br />code>
<p>{ { displayedText }}</p>
</div>
</template>
<script setup lang="ts">code>
import { ref } from 'vue'
const streamList = ref(['首先需要避免暴饮暴食,尽量保持规律的饮食习惯,避免过度饥饿或过饱。', '其次,应避免摄入过多油腻食物和高脂肪食物,以免加重胰腺负担。', '此外,还应注意控制饮酒量,避免酒精对胰腺的损害。'])
const currIndex = ref(0)
const displayedText = ref('') // 正在显示的文字
let timer: number | null = null
const startDisplayStr = () => {
if (timer) {
clearTimeout(timer!)
}
// 将数组中的字符串拼接起来
const res = streamList.value.join('')
if (currIndex.value < res.length) {
displayedText.value += res[currIndex.value]
currIndex.value++
setTimeout(startDisplayStr, 200)
} else {
clearTimeout(timer!)
timer = null
}
}
</script>
<style scoped></style>
二、setInterval
<template>
<div>
<button @click="getStream">逐字展示</button><br />code>
<p>{ { displayedText }}</p>
</div>
</template>
<script setup lang="ts">code>
import { ref } from 'vue'
const streamList = ref(['首先需要避免暴饮暴食,尽量保持规律的饮食习惯,避免过度饥饿或过饱。', '其次,应避免摄入过多油腻食物和高脂肪食物,以免加重胰腺负担。', '此外,还应注意控制饮酒量,避免酒精对胰腺的损害。'])
const currIndex = ref(0)
const displayedText = ref('') // 正在显示的文字
let timer: number | null = null
const getStream = () => {
timer = setInterval(displayAnswer, 200)
})
}
const displayAnswer = () => {
const text = streamList.value.join('')
displayedText.value += text[currIndex.value]
currIndex.value++
if (currIndex.value == text.length) {
clearInterval(timer!)
timer = null
}
}
</script>
<style scoped></style>
react+js
setInterval
import { useState, useRef, useEffect } from 'react';
import { Button } from 'antd';
const Xiaoan = () => {
const [stream, setStream] = useState('')
const [answerOutput, setAnswerOutput] = useState('') // 正在显示的文字
const typingRef = useRef(null); // 使用ref来存储定时器ID
const [isShowing, setIsShowing] = useState(false); // 是否开始展示
const start = () => {
setStream('这是一条测试语句')
setIsShowing(true)
}
// 逐字展示答案
const timeoutTextHandle = (callback) => {
let currIndex = 0
const chars = stream.split('')
const timer = setInterval(() => {
if (currIndex < chars.length) {
setAnswerOutput(prev => prev + chars[currIndex])
callback(chars[currIndex]) // 每增加一个字符调用回调,将当前的字符传给回调函数
currIndex++
} else {
clearInterval(timer)
setIsShowing(false)
}
}, 200)
typingRef.current = timer
}
useEffect(() => {
// 监听变量,触发函数
if (isShowing && stream) {
let fullChar = ''
history.current.push({type: 'ai', message: ''})
timeoutTextHandle(char => {
fullChar += char
let index = history.current.length - 1
history.current[index]['message'] = fullChar
})
}
return () => {
// 组件卸载时,清除定时器
if (typingRef.current) {
clearInterval(typingRef.current);
}
};
}, [isShowing, stream])
return (
<div>
<Button onClick={start}>开始</Button>
<div>展示:{answerOutput}</div>
</div>
)
}
export default Xiaoan
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。