展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > vue3如何实现chatgpt的打字机效果

vue3如何实现chatgpt的打字机效果

共识首先要明确一点,chatgpt返回的文本格式是markdown的,最基本的渲染方式就是把markdown文本转换为HTML文本,然后v-html渲染即可。这里的转换和代码高亮以及防XSS攻击用到了下面三个依赖库:marked将markdwon转为htmlhighlight处理代码高亮dompurify防止XSS攻击同时我们是可以在markdown中写html元素的,这意味着我们可以直接把光标元素放到最后!将markdown转为html并处理代码高亮先贴代码MarkdownRender.vueimpor

本文目录

    共识

    首先要明确一点,chatgpt 返回的文本格式是 markdown 的,最基本的渲染方式就是把 markdown 文本转换为 HTML 文本,然后 v-html 渲染即可。这里的转换和代码高亮以及防 XSS 攻击用到了下面三个依赖库:

    • marked 将markdwon 转为 html

    • highlight 处理代码高亮

    • dompurify 防止 XSS 攻击

    同时我们是可以在 markdown 中写 html 元素的,这意味着我们可以直接把光标元素放到最后!

    将 markdown 转为 html 并处理代码高亮

    先贴代码

    MarkdownRender.vue

    
    import {computed} from 'vue';
    import DOMPurify from 'dompurify';
    import {marked} from 'marked';
    import hljs from '//cdn.staticfile.org/highlight.js/11.7.0/es/highlight.min.js';
    import mdInCode from "@/utils/mdInCode"; // 用于判断是否显示光标
    
    const props = defineProps({
      // 输入的 markdown 文本
      text: {
        type: String,
        default: ""
      },
      // 是否需要显示光标?比如在消息流结束后是不需要显示光标的
      showCursor: {
        type: Boolean,
        default: false
      }
    })
    
    // 配置高亮
    marked.setOptions({
      highlight: function (code, lang) {
        try {
          if (lang) {
            return hljs.highlight(code, {language: lang}).value
          } else {
            return hljs.highlightAuto(code).value
          }
        } catch (error) {
          return code
        }
      },
      gfmtrue: true,
      breaks: true
    })
    
    // 计算最终要显示的 html 文本
    const html = computed(() => {
      // 将 markdown 转为 html
      function trans(text) {
        return DOMPurify.sanitize(marked.parse(text));
      }
      
      // 光标元素,可以用 css 美化成你想要的样子
      const cursor = '';
      if (props.showCursor) {
        // 判断 AI 正在回的消息是否有未闭合的代码块。
        const inCode = mdInCode(props.text)
        if (inCode) {
          // 有未闭合的代码块,不显示光标
          return trans(props.text);
        } else {
          // 没有未闭合的代码块,将光标元素追加到最后。
          return trans(props.text + cursor);
        }
      } else {
        // 父组件明确不显示光标
        return trans(props.text);
      }
    })
    
    
    
    
    
    

    可以发现最基本的 markdown 显示还是挺简单的,话就不多说了,都在注释里。

    我想你也许对判断消息中的代码块是否未闭合更感兴趣,那么就继续看下去吧!

    代码块是否未闭合

    markdown 有两种代码块,一种是 `code` ,另一种是 " code ",我叫他小代码块和大代码块。

    一开始我是想用正则去判断的,但是奈何有点复杂,我实在想不出应该如何去编写正则,让 chatgpt 写的正则也会判断失败,而且还要考虑到转义符,就算写出了正则,估计也会很复杂和难以维护。

    这里有请 chatgpt 简单介绍一下有限元状态机:

    有限元状态机(finite element state machine)是一种基于状态机的建模技术,它可以将系统的行为描述为一组状态和状态之间的转换。每个状态可以对应系统内的一种状态,而状态之间的转换则表示系统内部的转换过程。有限元状态机还可以用于系统的可靠性分析和测试,同时也可以作为软件工程中的一种建模工具,帮助代码实现、测试和调试等方面。

    在实际应用中,有限元状态机通常是通过自动化工具生成,并且可以用于控制系统、网络通信协议、软件接口等方面的设计和测试。由于有限元状态机具有自动化生成和完备性检查等优点,因此它已经成为了一种广泛应用的建模与测试工具。

    请站在web前端的视角下进行介绍

    从前端开发的角度来看,有限元状态机可以用于构建复杂的交互式Web应用程序。在Web应用程序中,有限元状态机可以描述用户界面的不同状态(例如,登录、注册、未登录等),以及状态之间的转换(例如,从登录状态转换到注册状态)。

    通常情况下,前端工程师使用JavaScript实现有限元状态机,包括定义状态、定义状态之间的转换规则、处理状态转换时的行为等。使用有限元状态机可以帮助前端工程师更好地掌控应用程序的状态,从而减少代码中的复杂条件分支和无法预测的行为。同时,有限元状态机也可以帮助前端团队共同理解应用程序的状态和转换规则,从而更好地协作开发和维护Web应用程序。

    总之,有限元状态机是一种非常有用的前端开发技术,可以帮助前端工程师更好地构建和管理Web应用程序的状态和行为,提高应用程序的可靠性和用户体验。

    回到正题,我可以一点一点的从头开始去解析 markdown 文本。想象这么一个简单的状态转换流程:

    • 初始状态为文本状态。

    • 遇到代码块标记,文本状态转换到代码块开始状态。

    • 再次遇到代码块标记,从代码块开始状态转换到文本状态。

    不过现实要更复杂一点,我们有小代码块和大代码块。有限元状态机的妙处就在这里,当处在小代码块状态的时候,我们不需要操心大代码块和正常文本的事,他的下一个状态只能是遇到小代码块的闭合标签,进入文本状态。

    理解了这些,再来看我的源码,才会发现他的精妙。

    const States = {
        text: 0, // 文本状态
        codeStartSm: 1, // 小代码块状态
        codeStartBig: 2, // 大代码块状态
    }
    
    /**
     * 判断 markdown 文本中是否有未闭合的代码块
     * @param text
     * @returns {boolean}
     */
    function isInCode(text) {
        let state = States.text
        let source = text
        let inStart = true // 是否处于文本开始状态,即还没有消费过文本
        while (source) { // 当文本被解析消费完后,就是个空字符串了,就能跳出循环
            let char = source.charAt(0) // 取第 0 个字
            switch (state) {
                case States.text:
                    if (/^\n?```/.test(source)) {
                        // 以 ``` 或者 \n``` 开头。表示大代码块开始。
                        // 一般情况下,代码块前面都需要换行。但是如果是在文本的开头,就不需要换行。
                        if (inStart || source.startsWith('\n')) {
                            state = States.codeStartBig
                        }
                        source = source.replace(/^\n?```/, '')
                    } else if (char === '\\') {
                        // 遇到转义符,跳过下一个字符
                        source = source.slice(2)
                    } else if (char === '`') {
                        // 以 ` 开头。表示小代码块开始。
                        state = States.codeStartSm
                        source = source.slice(1)
                    } else {
                        // 其他情况,直接消费当前字符
                        source = source.slice(1)
                    }
                    inStart = false
                    break
                case States.codeStartSm:
                    if (char === '`') {
                        // 遇到第二个 `,表示代码块结束
                        state = States.text
                        source = source.slice(1)
                    } else if (char === '\\') {
                        // 遇到转义符,跳过下一个字符
                        source = source.slice(2)
                    } else {
                        // 其他情况,直接消费当前字符
                        source = source.slice(1)
                    }
                    break
                case States.codeStartBig:
                    if (/^\n```/.test(source)) {
                        // 遇到第二个 ```,表示代码块结束
                        state = States.text
                        source = source.replace(/^\n```/, '')
                    } else {
                        // 其他情况,直接消费当前字符
                        source = source.slice(1)
                    }
                    break
            }
        }
        return state !== States.text
    }
    
    export default isInCode
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Vue3
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。