使用 Vue 3 和 TypeScript 实现带打字效果的仿 AI 分析展示组件
在这篇博客中,我将分享如何用 Vue 3 和 TypeScript 实现一个带打字效果的 AI 分析展示组件。该组件具有如下功能:
- 动态打字效果:模拟打字机逐步显示内容。
- 自动滚动:内容超出容器高度时自动滚动到最新位置。
1. 组件实现需求
我们需要实现一个点击触发获取 AI 分析结果的功能,并动态显示该分析内容,同时实现以下功能:
- 打字效果:AI 分析内容逐字展示,模仿打字机效果。
- 自动滚动:内容过长时,滚动条自动跟随展示最新的内容。
2. 组件功能分析
(1) 打字效果的实现
我们将 AI 分析结果通过定时器逐步显示,模拟打字机效果。每次定时器触发时,向内容中添加一批字符。
3. 代码实现
模板部分
在模板部分,我们定义了一个包含标题和内容的组件。点击标题后触发获取 AI 分析结果,并以打字效果显示内容。加载状态用 Element Plus 提供的 Loading 图标进行展示:
<template><div class="m_ai_analysis_title" @click="fetchAiAnalysis"><span class="iconfont icon-ai_icon m_ai_icon"></span><h3>{{ title }}</h3><el-icon v-if="aiLoading" class="is-loading"><Loading /></el-icon></div><div class="m_ai_analysis" v-if="printedContent"><div class="content-container" ref="contentContainer"><div class="typing-effect" v-html="printedContent"></div></div></div>
</template>
样式部分
为了实现打字机的视觉效果,我们通过 CSS 制作了光标闪烁效果,并设置了内容容器的滚动条样式:
.m_ai_analysis {padding: 12px 16px;border-top: 1px solid #eaeaea;background-color: #f9f9f9;border-radius: 8px;
}.m_ai_analysis_title {margin-top: 20px;display: flex;align-items: center;gap: 6px;cursor: pointer;
}.m_ai_analysis_title:hover .m_ai_icon {color: var(--el-color-primary);transform: scale(1.28);opacity: 0.88;
}h3 {font-size: 16px;font-weight: bold;
}.m_ai_icon {font-size: 28px;color: var(--el-color-primary);transition: all 0.3s ease;
}.m_ai_icon.disabled {cursor: not-allowed;color: #ccc;
}.content-container {max-height: 400px;overflow-y: auto;
}.typing-effect {white-space: pre-wrap;display: inline-block;position: relative;
}.typing-effect::after {content: '|';position: relative;font-size: 1.2em;color: black;animation: blink 1s step-end infinite;
}@keyframes blink {0%, 100% {opacity: 1;}50% {opacity: 0;}
}
核心逻辑部分
在 script 部分,我们使用 Vue 3 的 Composition API 和 TypeScript 来定义组件的核心功能:
<script setup lang="ts">
import commonApi from '@/api/commonApi';
import { Loading } from '@element-plus/icons-vue';
import { ref, watch, nextTick, onBeforeUnmount } from 'vue';const props = defineProps<{title: string;questionId: string | number | null;
}>();const printedContent = ref(''); // 打印内容
const aiLoading = ref(false); // 加载状态
const contentContainer = ref<HTMLElement | null>(null); // 滚动容器
let intervalId: ReturnType<typeof setInterval> | null = null; // 记录 intervalId// 监听 questionId 变化,清空内容
watch(() => props.questionId, async () => {printedContent.value = '';
});// 获取 AI 分析结果
const fetchAiAnalysis = async () => {if (!props.questionId) return;aiLoading.value = true;printedContent.value = '';try {const { data } = await commonApi.getGptAnalysis({ questionId: props.questionId });if (data) {await typeContent(data);}} catch (error) {console.error('Error fetching AI analysis:', error);} finally {aiLoading.value = false;}
};// 打字效果实现
const typeContent = async (content: string) => {let index = 0;const batchSize = 5; // 每次显示的字符数量intervalId = setInterval(async () => {if (index < content.length) {const nextChunk = content.slice(index, index + batchSize);printedContent.value += nextChunk;index += batchSize;await nextTick();scrollToBottom();} else {clearInterval(intervalId!);}}, 100);
};// 自动滚动到容器底部
const scrollToBottom = () => {if (contentContainer.value) {requestAnimationFrame(() => {contentContainer.value!.scrollTop = contentContainer.value!.scrollHeight;});}
};// 清理定时器
onBeforeUnmount(() => {if (intervalId) {clearInterval(intervalId);}
});
</script>
4. 关键技术点解析
(1) 打字效果
使用 setInterval 每隔一定时间添加一部分字符,直到整个内容被打印完成。这种方式模拟了一个打字机的效果,用户可以逐步看到分析内容的生成过程。
(2) 滚动到最新内容
通过 requestAnimationFrame 实现平滑的滚动效果,使得当新内容被添加时,页面自动滚动到底部,保持用户可以看到最新的内容。
效果图:

5. 总结
本文分享了如何在 Vue 3 和 TypeScript 项目中实现一个带打字效果的 AI 分析展示组件。
相关文章:
使用 Vue 3 和 TypeScript 实现带打字效果的仿 AI 分析展示组件
在这篇博客中,我将分享如何用 Vue 3 和 TypeScript 实现一个带打字效果的 AI 分析展示组件。该组件具有如下功能: 动态打字效果:模拟打字机逐步显示内容。自动滚动:内容超出容器高度时自动滚动到最新位置。 1. 组件实现需求 我…...
数据清洗-缺失值填充-K-NN算法(K-Nearest Neighbors, K-NN算法)
目录 一、安装所需的python包二、采用K-NN算法进行缺失值填充2.1代码(完整代码关注底部微信公众号获取)2.2以某个缺失值数据进行实战2.2.1代码运行过程截屏:2.2.2填充后的数据截屏: 三、K 近邻算法 (K-Nearest Neighbors, KNN) 介…...
爬虫----webpack
目录 一. 什么是webpack 出现的原因:同名函数 概念: 特征:大量缩进 webpack的格式 简单的webpack格式: 详细的webpack格式: 几个参数的运用 1. webpack数组形式 2. webpack对象格式 3.多个js文件打包 打印要扣的代码 …...
Spring Mybatis PageHelper分页插件 总结
1.简介 使用分页插件可以帮助我们自动分页,不用手动在写sql的分页逻辑。 2.配置步骤 在pom.xml中添加依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.11<…...
9、等保测评介绍
数据来源:9.等保测评介绍_哔哩哔哩_bilibili 信息系统等级测评 信息系统等级测评是测评机构依据国家信息安全等级保护制度的规定,按照相关管理规范和技术标准,对未涉及国家秘密的信息系统的安全等级保护状况进行检测评估的活动。 等级测评…...
解决Gson将长数字( json字符串)转换为科学记数法格式
Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。 依赖 Gradle: dependencies {implementation com.google.code.gson:gson:2.11.0 }…...
php环境搭建教程
PHP环境搭建教程 在构建和开发PHP应用程序时,搭建一个稳定、高效的PHP环境是基础且关键的一步。本教程将详细介绍如何在不同操作系统(Windows和Linux)上搭建PHP环境,包括Apache服务器的安装与配置、PHP的安装与配置、MySQL的安装…...
测试ASP.NET Core的WebApi项目调用WebService
虚拟机中部署的匿名访问的WebService,支持简单的加减乘除操作。本文记录在WebApi中调用该WebService的方式。 VS2022创建WebApi项目,然后在解决方案资源管理器的Connected Services节点点右键,选择管理连接的服务菜单。 点击下图圈红处…...
【用Java学习数据结构系列】对象的比较(Priority Queue实现的前提)
看到这句话的时候证明:此刻你我都在努力 加油陌生人 个人主页:Gu Gu Study 专栏:用Java学习数据结构系列 喜欢的一句话: 常常会回顾努力的自己,所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者ÿ…...
快手视频怎么保存到相册?(详细操作)
随着短视频的流行,快手已经成为越来越多人日常生活的一部分。无论是搞笑片段、旅行记录,还是生活点滴,用户们每天都会在快手上浏览到大量有趣的视频。有时候,我们会遇到特别想保存的视频,想要分享到朋友圈,…...
为什么 ECB 模式不安全
我们先来简单了解下 ECB 模式是如何工作的 ECB 模式不涉及链接模式,所以也就用不着初始化向量,那么相同的明文分组就会被加密成相同的密文分组,而且每个分组运算都是独立的,这也就意味着可以并行提高运算效率,但也正是…...
『功能项目』事件中心处理怪物死亡【55】
本章项目成果展示 我们打开上一篇54回调函数处理死亡的项目, 本章要做的事情是用事件中心处理怪物死亡后的逻辑 首先打开之前事件中心脚本(不做更改,调用即可): using System.Collections.Generic; using UnityEngine…...
一个安卓鸿蒙化工具
DevEco插件,为已有安卓项目鸿蒙化加速。 目前支持: 1、安卓Vector Assets转svg; 2、json转ets model; 3、kotlin model转ets model; 下载地址:andtoharplugin1.1.0 安装: deveco插件安装选硬…...
PyQt5库学习之QFileDialog.getExistingDirectory函数
PyQt5库学习之QFileDialog.getExistingDirectory函数 一、简介 QFileDialog.getExistingDirectory 是 PyQt5 中的一个函数,它提供了一个标准的目录选择对话框,允许用户选择一个已存在的目录。这个函数是 QFileDialog 类的一部分,通常用于打开…...
AUTOSAR_EXP_ARAComAPI的5章笔记(9)
☞ 返回总目录 5.4 骨架类(Skeleton Class) 骨架类是由AUTOSAR 元模型的服务接口描述(SI description)生成的。ara::com对生成的骨架类的接口进行了标准化。自适应平台(AP)产品供应商的工具链将生成一个完…...
京东-第2题-撞车
Powered by:NEFU AB-IN Link 文章目录 京东-第2题-撞车题意思路代码 京东-第2题-撞车 题意 一条单向单车道的道路上有n辆车,第i辆车位于 xi;,速度大小为 vi。 显然,如果车辆保持此速度行驶下去,在大多数情况下都会发生碰撞。 现…...
Vue3流程图插件-Vue Flow
1、安装:通过 npm 或 yarn 安装 Vue Flow。 npm install vueflow/core# 或者yarn add vueflow/core 2、引入:在你的 Vue 3 项目中引入 Vue Flow。 import { VueFlow, Background, Controls, MiniMap } from vueflow/core;3、使用:在 Vue…...
初始网络编程(下)
所属专栏:Java学习 1. TCP 的简单示例 同时,由于 TCP 是面向字节流的传输,所以说传输的基本单位是字节,接受发送都是使用的字节流 方法签名 方法说明 Socket accept() 开始监听指定端口(创建时绑定的端口&…...
java计算机毕设课设—土地档案管理系统(附源码、文章、相关截图、部署视频)
这是什么系统? 资源获取方式在最下方 java计算机毕设课设—土地档案管理系统(附源码、文章、相关截图、部署视频) 土地档案管理系统是一种将传统纸质档案进行数字化管理的软件。通过该系统,用户能够高效地进行土地档案的存储、查阅、修改和删除等操作…...
第4步CentOS配置SSH服务用SSH终端XShell等连接方便文件上传或其它操作
宿主机的VM安装CENTOS文件无法快速上传,也不方便输入命令行,用SSH终端xshell连接虚拟机的SSH工具就方便多了,实现VM所在宿主机Win10上的xshell能连接vm的centos要实现以下几个环节 1、确保宿主机与虚拟机的连通性。 2、虚拟机安装SSH服务&…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
