国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue3 實(shí)現(xiàn) chatgpt 的打字機(jī)效果

這篇具有很好參考價(jià)值的文章主要介紹了vue3 實(shí)現(xiàn) chatgpt 的打字機(jī)效果。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

在做 chatgpt 鏡像站的時(shí)候,發(fā)現(xiàn)有些鏡像站是沒做打字機(jī)的光標(biāo)效果的,就只是文字輸出,是他們不想做嗎?反正我想做。于是我仔細(xì)研究了一下,實(shí)現(xiàn)了打字機(jī)效果加光標(biāo)的效果,現(xiàn)在分享一下我的解決方案以及效果圖

vue3 實(shí)現(xiàn) chatgpt 的打字機(jī)效果

共識(shí)

首先要明確一點(diǎn),chatgpt 返回的文本格式是 markdown 的,最基本的渲染方式就是把 markdown 文本轉(zhuǎn)換為 HTML 文本,然后 v-html 渲染即可。這里的轉(zhuǎn)換和代碼高亮以及防 XSS 攻擊用到了下面三個(gè)依賴庫(kù):

  • marked 將markdwon 轉(zhuǎn)為 html
  • highlight 處理代碼高亮
  • dompurify 防止 XSS 攻擊

同時(shí)我們是可以在 markdown 中寫 html 元素的,這意味著我們可以直接把光標(biāo)元素放到最后!

將 markdown 轉(zhuǎn)為 html 并處理代碼高亮

先貼代碼

MarkdownRender.vue

<script setup>
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"; // 用于判斷是否顯示光標(biāo)

const props = defineProps({
  // 輸入的 markdown 文本
  text: {
    type: String,
    default: ""
  },
  // 是否需要顯示光標(biāo)?比如在消息流結(jié)束后是不需要顯示光標(biāo)的
  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
})

// 計(jì)算最終要顯示的 html 文本
const html = computed(() => {
  // 將 markdown 轉(zhuǎn)為 html
  function trans(text) {
    return DOMPurify.sanitize(marked.parse(text));
  }
  
  // 光標(biāo)元素,可以用 css 美化成你想要的樣子
  const cursor = '<span class="cursor"></span>';
  if (props.showCursor) {
    // 判斷 AI 正在回的消息是否有未閉合的代碼塊。
    const inCode = mdInCode(props.text)
    if (inCode) {
      // 有未閉合的代碼塊,不顯示光標(biāo)
      return trans(props.text);
    } else {
      // 沒有未閉合的代碼塊,將光標(biāo)元素追加到最后。
      return trans(props.text + cursor);
    }
  } else {
    // 父組件明確不顯示光標(biāo)
    return trans(props.text);
  }
})

</script>

<template>
  <!-- tailwindcss:leading-7 控制行高為1.75rem -->
  <div v-html="html" class="markdown leading-7">
  </div>
</template>

<style lang="postcss">
/** 設(shè)置代碼塊樣式 **/
.markdown pre {
  @apply bg-[#282c34] p-4 mt-4 rounded-md text-white w-full overflow-x-auto;
}
.markdown code {
  width: 100%;
}

/** 控制段落間的上下邊距 **/
.markdown p {
  margin: 1.25rem 0;
}
.markdown p:first-child {
  margin-top: 0;
}

/** 小代碼塊樣式,對(duì)應(yīng) markdown 的 `code` **/
.markdown :not(pre) > code {
  @apply bg-[#282c34] px-1 py-[2px] text-[#e06c75] rounded-md;
}

/** 列表樣式 **/
.markdown ol {
  list-style-type: decimal;
  padding-left: 40px;
}
.markdown ul {
  list-style-type: disc;
  padding-left: 40px;
}

/** 光標(biāo)樣式 **/
.markdown .cursor {
  display: inline-block;
  width: 2px;
  height: 20px;
  @apply bg-gray-800 dark:bg-gray-100;
  animation: blink 1.2s step-end infinite;
  margin-left: 2px;
  vertical-align: sub;
}
@keyframes blink {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
</style>

可以發(fā)現(xiàn)最基本的 markdown 顯示還是挺簡(jiǎn)單的,話就不多說(shuō)了,都在注釋里。

我想你也許對(duì)判斷消息中的代碼塊是否未閉合更感興趣,那么就繼續(xù)看下去吧!

代碼塊是否未閉合

markdown 有兩種代碼塊,一種是 `code` ,另一種是 ``` code ```,我叫他小代碼塊和大代碼塊。

一開始我是想用正則去判斷的,但是奈何有點(diǎn)復(fù)雜,我實(shí)在想不出應(yīng)該如何去編寫正則,讓 chatgpt 寫的正則也會(huì)判斷失敗,而且還要考慮到轉(zhuǎn)義符,就算寫出了正則,估計(jì)也會(huì)很復(fù)雜和難以維護(hù)。

經(jīng)過(guò)短暫的苦思冥想后,我想到了之前在 《Vue.js設(shè)計(jì)與實(shí)現(xiàn)》 中看到的用有限元狀態(tài)機(jī)解析 html 文本的方案。

這里有請(qǐng) chatgpt 簡(jiǎn)單介紹一下有限元狀態(tài)機(jī):

有限元狀態(tài)機(jī)(finite element state machine)是一種基于狀態(tài)機(jī)的建模技術(shù),它可以將系統(tǒng)的行為描述為一組狀態(tài)和狀態(tài)之間的轉(zhuǎn)換。每個(gè)狀態(tài)可以對(duì)應(yīng)系統(tǒng)內(nèi)的一種狀態(tài),而狀態(tài)之間的轉(zhuǎn)換則表示系統(tǒng)內(nèi)部的轉(zhuǎn)換過(guò)程。有限元狀態(tài)機(jī)還可以用于系統(tǒng)的可靠性分析和測(cè)試,同時(shí)也可以作為軟件工程中的一種建模工具,幫助代碼實(shí)現(xiàn)、測(cè)試和調(diào)試等方面。

在實(shí)際應(yīng)用中,有限元狀態(tài)機(jī)通常是通過(guò)自動(dòng)化工具生成,并且可以用于控制系統(tǒng)、網(wǎng)絡(luò)通信協(xié)議、軟件接口等方面的設(shè)計(jì)和測(cè)試。由于有限元狀態(tài)機(jī)具有自動(dòng)化生成和完備性檢查等優(yōu)點(diǎn),因此它已經(jīng)成為了一種廣泛應(yīng)用的建模與測(cè)試工具。

請(qǐng)站在web前端的視角下進(jìn)行介紹

從前端開發(fā)的角度來(lái)看,有限元狀態(tài)機(jī)可以用于構(gòu)建復(fù)雜的交互式Web應(yīng)用程序。在Web應(yīng)用程序中,有限元狀態(tài)機(jī)可以描述用戶界面的不同狀態(tài)(例如,登錄、注冊(cè)、未登錄等),以及狀態(tài)之間的轉(zhuǎn)換(例如,從登錄狀態(tài)轉(zhuǎn)換到注冊(cè)狀態(tài))。

通常情況下,前端工程師使用JavaScript實(shí)現(xiàn)有限元狀態(tài)機(jī),包括定義狀態(tài)、定義狀態(tài)之間的轉(zhuǎn)換規(guī)則、處理狀態(tài)轉(zhuǎn)換時(shí)的行為等。使用有限元狀態(tài)機(jī)可以幫助前端工程師更好地掌控應(yīng)用程序的狀態(tài),從而減少代碼中的復(fù)雜條件分支和無(wú)法預(yù)測(cè)的行為。同時(shí),有限元狀態(tài)機(jī)也可以幫助前端團(tuán)隊(duì)共同理解應(yīng)用程序的狀態(tài)和轉(zhuǎn)換規(guī)則,從而更好地協(xié)作開發(fā)和維護(hù)Web應(yīng)用程序。

總之,有限元狀態(tài)機(jī)是一種非常有用的前端開發(fā)技術(shù),可以幫助前端工程師更好地構(gòu)建和管理Web應(yīng)用程序的狀態(tài)和行為,提高應(yīng)用程序的可靠性和用戶體驗(yàn)。

回到正題,我可以一點(diǎn)一點(diǎn)的從頭開始去解析 markdown 文本。想象這么一個(gè)簡(jiǎn)單的狀態(tài)轉(zhuǎn)換流程:

  • 初始狀態(tài)為文本狀態(tài)。
  • 遇到代碼塊標(biāo)記,文本狀態(tài)轉(zhuǎn)換到代碼塊開始狀態(tài)。
  • 再次遇到代碼塊標(biāo)記,從代碼塊開始狀態(tài)轉(zhuǎn)換到文本狀態(tài)。

不過(guò)現(xiàn)實(shí)要更復(fù)雜一點(diǎn),我們有小代碼塊和大代碼塊。有限元狀態(tài)機(jī)的妙處就在這里,當(dāng)處在小代碼塊狀態(tài)的時(shí)候,我們不需要操心大代碼塊和正常文本的事,他的下一個(gè)狀態(tài)只能是遇到小代碼塊的閉合標(biāo)簽,進(jìn)入文本狀態(tài)。

理解了這些,再來(lái)看我的源碼,才會(huì)發(fā)現(xiàn)他的精妙。

const States = {
    text: 0, // 文本狀態(tài)
    codeStartSm: 1, // 小代碼塊狀態(tài)
    codeStartBig: 2, // 大代碼塊狀態(tài)
}

/**
 * 判斷 markdown 文本中是否有未閉合的代碼塊
 * @param text
 * @returns {boolean}
 */
function isInCode(text) {
    let state = States.text
    let source = text
    let inStart = true // 是否處于文本開始狀態(tài),即還沒有消費(fèi)過(guò)文本
    while (source) { // 當(dāng)文本被解析消費(fèi)完后,就是個(gè)空字符串了,就能跳出循環(huán)
        let char = source.charAt(0) // 取第 0 個(gè)字
        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 === '\\') {
                    // 遇到轉(zhuǎn)義符,跳過(guò)下一個(gè)字符
                    source = source.slice(2)
                } else if (char === '`') {
                    // 以 ` 開頭。表示小代碼塊開始。
                    state = States.codeStartSm
                    source = source.slice(1)
                } else {
                    // 其他情況,直接消費(fèi)當(dāng)前字符
                    source = source.slice(1)
                }
                inStart = false
                break
            case States.codeStartSm:
                if (char === '`') {
                    // 遇到第二個(gè) `,表示代碼塊結(jié)束
                    state = States.text
                    source = source.slice(1)
                } else if (char === '\\') {
                    // 遇到轉(zhuǎn)義符,跳過(guò)下一個(gè)字符
                    source = source.slice(2)
                } else {
                    // 其他情況,直接消費(fèi)當(dāng)前字符
                    source = source.slice(1)
                }
                break
            case States.codeStartBig:
                if (/^\n```/.test(source)) {
                    // 遇到第二個(gè) ```,表示代碼塊結(jié)束
                    state = States.text
                    source = source.replace(/^\n```/, '')
                } else {
                    // 其他情況,直接消費(fèi)當(dāng)前字符
                    source = source.slice(1)
                }
                break
        }
    }
    return state !== States.text
}

export default isInCode

到這里,就已經(jīng)實(shí)現(xiàn)了一個(gè) chatgpt 消息渲染了。喜歡的話點(diǎn)個(gè)贊吧!謝謝!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-453691.html

到了這里,關(guān)于vue3 實(shí)現(xiàn) chatgpt 的打字機(jī)效果的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 微信小程序-接入sse數(shù)據(jù)流并實(shí)現(xiàn)打字機(jī)效果( ChatGPT )

    微信小程序-接入sse數(shù)據(jù)流并實(shí)現(xiàn)打字機(jī)效果( ChatGPT )

    從流中獲取的數(shù)據(jù)格式如下 小程序調(diào)用SSE接口 我這邊接收到的數(shù)據(jù)類型為Uint8Array,需要處理成text文本(如上圖) 使對(duì)話有打字機(jī)效果 參考自:小程序?qū)崿F(xiàn) ChatGPT 聊天打字兼自動(dòng)滾動(dòng)效果 完整代碼

    2024年04月09日
    瀏覽(55)
  • ChatGPT 打字機(jī)效果原理

    ChatGPT 打字機(jī)效果原理

    在初次使用 ChatGPT 時(shí),我就被打字機(jī)的視覺效果吸引??偸歉杏X似曾相識(shí),因?yàn)榻?jīng)常在一些科幻電影中看到,高級(jí)文明回傳的信息在通訊設(shè)備的屏幕上以打字機(jī)效果逐步出現(xiàn),在緊張的氛圍下,輸出人類可讀的內(nèi)容,拉動(dòng)著觀眾的神經(jīng),一步步將故事情節(jié)推向高潮。 在很早之

    2024年02月04日
    瀏覽(24)
  • 大模型問(wèn)答助手前端實(shí)現(xiàn)打字機(jī)效果

    隨著現(xiàn)代技術(shù)的快速發(fā)展,即時(shí)交互變得越來(lái)越重要。用戶不僅希望獲取信息,而且希望以更直觀和實(shí)時(shí)的方式體驗(yàn)它。這在聊天應(yīng)用程序和其他實(shí)時(shí)通信工具中尤為明顯,用戶習(xí)慣看到對(duì)方正在輸入的提示。 ChatGPT,作為 OpenAI 的代表性產(chǎn)品之一,不僅為用戶提供了強(qiáng)大的自

    2024年02月08日
    瀏覽(23)
  • 記錄--20行js就能實(shí)現(xiàn)逐字顯示效果???-打字機(jī)效果

    記錄--20行js就能實(shí)現(xiàn)逐字顯示效果???-打字機(jī)效果

    橫版 豎版 可以看到文字是一段一段的并且獨(dú)占一行,使用段落標(biāo)簽p表示一行 一段文字內(nèi),字是一個(gè)一個(gè)顯示的,所以這里每一個(gè)字都用一個(gè)span標(biāo)簽裝起來(lái) 每一個(gè)字都是從透明到不透明的過(guò)渡效果,使用css3的過(guò)渡屬性transition讓每個(gè)字都從透明過(guò)渡到不透明 這里只需要一個(gè)

    2024年02月06日
    瀏覽(26)
  • 前端發(fā)送Fetch請(qǐng)求實(shí)現(xiàn)流式請(qǐng)求、模擬打字機(jī)效果等

    前端需要接收后端的流式返回?cái)?shù)據(jù),并實(shí)時(shí)渲染。 普通的xhr請(qǐng)求都是等http協(xié)議數(shù)據(jù)包一次性返回之后才渲染,類似于ChatGPT的Http接口內(nèi)容類型為text/event-stream。這種內(nèi)容類型需要與瀏覽器建立持久連接并持續(xù)監(jiān)聽服務(wù)器返回的數(shù)據(jù)。 npm 方式安裝類庫(kù) 使用 調(diào)用 fetchEventSource

    2024年02月13日
    瀏覽(25)
  • Unity Text文本實(shí)現(xiàn)打字機(jī)(一個(gè)一個(gè)出來(lái))的效果

    Unity Text文本要實(shí)現(xiàn)打字機(jī),即一個(gè)個(gè)文字出來(lái)的效果,可以通過(guò)代碼把text文本字符串拆成一個(gè)個(gè)字符然后添加到文本中。 具體實(shí)現(xiàn): 新建一個(gè)控制腳本:TypewriteController.cs,并編寫以下代碼: 此控制腳本先把腳本文本獲取后賦給一個(gè)字符串變量,然后置空文本內(nèi)容,再通過(guò)

    2024年01月25日
    瀏覽(63)
  • 【JS真好玩】自動(dòng)打字機(jī)效果

    【JS真好玩】自動(dòng)打字機(jī)效果

    大家好,今天實(shí)現(xiàn)一個(gè)自動(dòng)打字機(jī)效果,旨在實(shí)現(xiàn)一些網(wǎng)上很小的demo樣例,通過(guò)每一個(gè)小demo能夠鞏固一下我們的前端基礎(chǔ)知識(shí)。 今天,主要利用定時(shí)器、flex布局實(shí)現(xiàn)一個(gè)自動(dòng)打字機(jī)效果。 效果展示 : 考察 : flex布局、定時(shí)器、字符串 建議用時(shí)20~35min 我們主要把自動(dòng)打字

    2024年02月10日
    瀏覽(19)
  • 僅使用 CSS 創(chuàng)建打字機(jī)動(dòng)畫效果

    僅使用 CSS 創(chuàng)建打字機(jī)動(dòng)畫效果

    創(chuàng)建打字機(jī)效果比您想象的要容易。雖然實(shí)現(xiàn)這種效果的最常見方法是使用 JavaScript,但我們也可以使用純 CSS 來(lái)創(chuàng)建我們的打字機(jī)動(dòng)畫。 在本文中,我們將了解如何僅使用 CSS 創(chuàng)建打字機(jī)動(dòng)畫效果。它簡(jiǎn)單、漂亮、容易。我們還將看看使用 CSS 與 JavaScript 創(chuàng)建這種效果的利弊

    2024年02月13日
    瀏覽(24)
  • 聊聊大模型"打字機(jī)"效果的背后技術(shù)——SSE

    聊聊大模型"打字機(jī)"效果的背后技術(shù)——SSE

    轉(zhuǎn)載請(qǐng)注明出處:https://www.cnblogs.com/zhiyong-ITNote SSE:Server Sent Event;服務(wù)器發(fā)送事件。 Server-Sent Events(SSE)是一種由服務(wù)器向客戶端推送實(shí)時(shí)數(shù)據(jù)的技術(shù)。它是構(gòu)建基于事件的、服務(wù)器到客戶端的通信的一種方法,特別適用于需要實(shí)時(shí)更新和推送信息的應(yīng)用場(chǎng)景,如實(shí)時(shí)通知

    2024年03月27日
    瀏覽(23)
  • 【CSS3】CSS3 動(dòng)畫 ⑤ ( 動(dòng)畫速度曲線 | 設(shè)置動(dòng)畫步長(zhǎng) | 動(dòng)畫勻速執(zhí)行 | 動(dòng)畫分 2 步執(zhí)行 | 使用動(dòng)畫步長(zhǎng)實(shí)現(xiàn)打字機(jī)效果 )

    【CSS3】CSS3 動(dòng)畫 ⑤ ( 動(dòng)畫速度曲線 | 設(shè)置動(dòng)畫步長(zhǎng) | 動(dòng)畫勻速執(zhí)行 | 動(dòng)畫分 2 步執(zhí)行 | 使用動(dòng)畫步長(zhǎng)實(shí)現(xiàn)打字機(jī)效果 )

    CSS3 樣式中 , 設(shè)置 動(dòng)畫速度曲線 的屬性是 animation-timing-function 屬性 ; animation-timing-function 屬性定義了動(dòng)畫從 初始 CSS 樣式 變?yōu)?結(jié)束狀態(tài) 時(shí) 所消耗的時(shí)間 ; animation-timing-function 屬性常用 屬性值 如下 : linear : 動(dòng)畫在整個(gè)執(zhí)行過(guò)程中速度都是勻速的 ; ease : 默認(rèn)屬性值 , 動(dòng)畫首先

    2024年02月13日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包