前端实现逐字展示效果

杨了仰头 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



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。