国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Inhaltsverzeichnis
共識(shí)
將 markdown 轉(zhuǎn)為 html 并處理代碼高亮
代碼塊是否未閉合
Heim Web-Frontend View.js Detailliertes Beispiel für vue3, das den Schreibmaschineneffekt von chatgpt realisiert

Detailliertes Beispiel für vue3, das den Schreibmaschineneffekt von chatgpt realisiert

Apr 18, 2023 pm 03:40 PM
Frontend vue.js chatgpt

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

Kapture 2023-04-14 at 14.02.32.gif

共識(shí)

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

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

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

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

先貼代碼

MarkdownRender.vue

<script setup>
import {computed} from &#39;vue&#39;;
import DOMPurify from &#39;dompurify&#39;;
import {marked} from &#39;marked&#39;;
import hljs from &#39;//cdn.staticfile.org/highlight.js/11.7.0/es/highlight.min.js&#39;;
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 = &#39;<span></span>&#39;;
  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>
/** 設(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)單的,話就不多說了,都在注釋里。

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

代碼塊是否未閉合

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

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

經(jīng)過短暫的苦思冥想后,我想到了之前在 《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)換過程。有限元狀態(tài)機(jī)還可以用于系統(tǒng)的可靠性分析和測(cè)試,同時(shí)也可以作為軟件工程中的一種建模工具,幫助代碼實(shí)現(xiàn)、測(cè)試和調(diào)試等方面。

在實(shí)際應(yīng)用中,有限元狀態(tài)機(jī)通常是通過自動(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ā)的角度來看,有限元狀態(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ù)雜條件分支和無法預(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)。

不過現(xiàn)實(shí)要更復(fù)雜一點(diǎn),我們有小代碼塊和大代碼塊。有限元狀態(tài)機(jī)的妙處就在這里,當(dāng)處在小代碼塊狀態(tài)的時(shí)候,我們不需要操心大代碼塊和正常文本的事,他的下一個(gè)狀態(tài)只能是遇到小代碼塊的閉合標(biāo)簽,進(jìn)入文本狀態(tà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)過文本
    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(&#39;\n&#39;)) {
                        state = States.codeStartBig
                    }
                    source = source.replace(/^\n?```/, &#39;&#39;)
                } else if (char === &#39;\\&#39;) {
                    // 遇到轉(zhuǎn)義符,跳過下一個(gè)字符
                    source = source.slice(2)
                } else if (char === &#39;`&#39;) {
                    // 以 ` 開頭。表示小代碼塊開始。
                    state = States.codeStartSm
                    source = source.slice(1)
                } else {
                    // 其他情況,直接消費(fèi)當(dāng)前字符
                    source = source.slice(1)
                }
                inStart = false
                break
            case States.codeStartSm:
                if (char === &#39;`&#39;) {
                    // 遇到第二個(gè) `,表示代碼塊結(jié)束
                    state = States.text
                    source = source.slice(1)
                } else if (char === &#39;\\&#39;) {
                    // 遇到轉(zhuǎn)義符,跳過下一個(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```/, &#39;&#39;)
                } 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è)贊吧!謝謝!

Das obige ist der detaillierte Inhalt vonDetailliertes Beispiel für vue3, das den Schreibmaschineneffekt von chatgpt realisiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erkl?rung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Hei?e KI -Werkzeuge

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?e Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Hei?e Themen

PHP-Tutorial
1502
276
Vue.js vs. React: projektspezifische überlegungen Vue.js vs. React: projektspezifische überlegungen Apr 09, 2025 am 12:01 AM

Vue.js eignet sich für kleine und mittelgro?e Projekte und schnelle Iterationen, w?hrend React für gro?e und komplexe Anwendungen geeignet ist. 1) Vue.js ist einfach zu bedienen und für Situationen geeignet, in denen das Team nicht ausreicht oder die Projektskala klein ist. 2) React hat ein reichhaltigeres ?kosystem und eignet sich für Projekte mit hoher Leistung und komplexen funktionalen Bedürfnissen.

Ist Vue.js schwer zu lernen? Ist Vue.js schwer zu lernen? Apr 04, 2025 am 12:02 AM

Vue.js ist nicht schwer zu lernen, insbesondere für Entwickler mit einer JavaScript -Stiftung. 1) Sein progressives Design und das reaktionsschnelle System vereinfachen den Entwicklungsprozess. 2) Komponentenbasierte Entwicklung macht das Codemanagement effizienter. 3) Die Nutzungsbeispiele zeigen eine grundlegende und fortgeschrittene Verwendung. 4) H?ufige Fehler k?nnen durch VEDEVTOOLS debuggen werden. 5) Leistungsoptimierung und Best Practices, z. B. die Verwendung von V-IF/V-Shows und Schlüsselattributen, k?nnen die Anwendungseffizienz verbessern.

Wird Vue für Frontend oder Backend verwendet? Wird Vue für Frontend oder Backend verwendet? Apr 03, 2025 am 12:07 AM

Vue.js wird haupts?chlich für die Front-End-Entwicklung verwendet. 1) Es handelt sich um ein leichtes und flexibles JavaScript-Framework, das sich auf den Aufbau von Benutzeroberfl?chen und einseitigen Anwendungen konzentriert. 2) Der Kern von Vue.js ist das reaktionsschnelle Datensystem, und die Ansicht wird automatisch aktualisiert, wenn sich die Daten ?ndert. 3) Es unterstützt die Komponentenentwicklung und die Benutzeroberfl?che kann in unabh?ngige und wiederverwendbare Komponenten aufgeteilt werden.

Das Verst?ndnis der Hauptfunktion von React: Die Frontend -Perspektive Das Verst?ndnis der Hauptfunktion von React: Die Frontend -Perspektive Apr 18, 2025 am 12:15 AM

Zu den Hauptfunktionen von React geh?ren komponentiertes Denken, Staatsmanagement und virtuelles DOM. 1) Die Idee der Komponentierung erm?glicht es, die Benutzeroberfl?che in wiederverwendbare Teile aufzuteilen, um die Lesbarkeit und Wartbarkeit der Code zu verbessern. 2) Das staatliche Management verwaltet dynamische Daten durch Status und Requisiten und ?ndert sich ausl?sen UI -Updates. 3) Aktualisieren Sie die Benutzeroberfl?che virtuelle DOM -Optimierungsleistung durch die Berechnung des Mindestbetriebs der DOM -Replik im Speicher.

VUE.JS: Definieren seiner Rolle in der Webentwicklung VUE.JS: Definieren seiner Rolle in der Webentwicklung Apr 18, 2025 am 12:07 AM

Vue.js 'Rolle in der Webentwicklung besteht darin, als progressives JavaScript -Framework zu fungieren, das den Entwicklungsprozess vereinfacht und die Effizienz verbessert. 1) Es erm?glicht Entwicklern, sich auf Gesch?ftslogik durch reaktionsschnelle Datenbindung und Komponentenentwicklung zu konzentrieren. 2) Das Arbeitsprinzip von Vue.js beruht auf reaktionsschnellen Systemen und virtuellem DOM, um die Leistung zu optimieren. 3) In den tats?chlichen Projekten ist es üblich, Vuex zu verwenden, um den globalen Zustand zu verwalten und die Datenreaktionsf?higkeit zu optimieren.

Vue.js und der Frontend Stack: Verst?ndnis der Verbindungen Vue.js und der Frontend Stack: Verst?ndnis der Verbindungen Apr 24, 2025 am 12:19 AM

Vue.js ist eng in den Front-End-Technologie-Stack integriert, um die Entwicklungseffizienz und die Benutzererfahrung zu verbessern. 1) Konstruktionstools: Integrieren Sie sich in Webpack und Rollup, um eine modulare Entwicklung zu erzielen. 2) Staatsmanagement: Integrieren Sie sich in Vuex, um den komplexen Anwendungsstatus zu verwalten. 3) Routing: Integrieren Sie sich in Vuerouter, um einseitige Anwendungsrouting zu realisieren. 4) CSS -Pr?prozessor: Unterstützt SASS und weniger, um die Stilentwicklungseffizienz zu verbessern.

Vue.js vs. React: Vergleich der Leistung und Effizienz Vue.js vs. React: Vergleich der Leistung und Effizienz Apr 28, 2025 am 12:12 AM

Vue.js und React haben jeweils eigene Vorteile: Vue.js ist für kleine Anwendungen und schnelle Entwicklung geeignet, w?hrend React für gro?e Anwendungen und komplexes Staatsmanagement geeignet ist. 1.Vue.js realisiert automatisches Update über ein reaktionsschnelles System, das für kleine Anwendungen geeignet ist. 2.React verwendet virtuelle DOM- und Diff -Algorithmen, die für gro?e und komplexe Anwendungen geeignet sind. Bei der Auswahl eines Frameworks müssen Sie Projektanforderungen und Teamtechnologie -Stack in Betracht ziehen.

Vue.js im Frontend: Anwendungen und Beispiele in realer Welt Vue.js im Frontend: Anwendungen und Beispiele in realer Welt Apr 11, 2025 am 12:12 AM

Vue.js ist ein progressives JavaScript -Framework, das zum Erstellen komplexer Benutzeroberfl?chen geeignet ist. 1) Zu seinen Kernkonzepten geh?ren Reaktionsdaten, Komponentierungen und virtuelle DOM. 2) In praktischen Anwendungen kann es durch den Aufbau von Todo -Anwendungen und die Integration von Vuerouter demonstriert werden. 3) Beim Debuggen wird empfohlen, VODEVTOOLS und CONSOLE.LOG zu verwenden. 4) Die Leistungsoptimierung kann durch V-IF/V-Show, Listen-Rendering-Optimierung, asynchrone Belastung von Komponenten usw. erreicht werden.

See all articles