likes
comments
collection
share

Prism.js+Vue3+vite实现实时代码块渲染

作者站长头像
站长
· 阅读数 40

前言

五一假期,本想躺平好好享受假期,但是一直想写一个和chatgpt差不多页面,但是实现路程坎坎坷坷,此文是为了记录一下亲测有效的代码块高亮实现。实际实现效果为下图,接口是通过ws协议实时渲染展示代码块,不是静态渲染,亦可实现动态添加代码复制功能。 Prism.js+Vue3+vite实现实时代码块渲染

基础使用

先安装Prism.js,能实现代码块高亮的插件有很多这里选用了Prism.js,它是比较轻量级而且功能强大可以通过plugin进行可选功能扩展。 安装

//安装Prism.js编译器
npm install prismjs -S
//可选项,主要是进行扩展更功能控制和样式主体控制
//若不安装需要在mian.ts中引入想要的主题样式
//同时需要注意的是这是vite版本安装命令
npm install vite-plugin-prismjs -D

vite.config.ts配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { prismjsPlugin } from "vite-plugin-prismjs"
export default defineConfig(({ command }) => {
  const prodMock = true
  return {
    plugins: [
      vue(),
      prismjsPlugin({
        languages: 'all',
        plugins: ['line-numbers', 'copy-to-clipboard'], //官网有其他功能,这里开启行数和复制按钮功能
        theme: 'tomorrow',
        css: true,
      }),
    ],
  }
})

使用页面使用 我们将需要被代码高亮的code片段通过Prism.highlight进行处理,他会输出加上类名的格式化后的jsx标签,在vue中直接用v-html指令进行渲染即可

import Prism from "prismjs";
let copyCodeSting=`function deepCopy(obj) { xxxx}`
let codeString = Prism.highlight(
            copyCodeSting,//需要格式化的片段
            Prism.languages.javascript,//js语言
            "javascript"//输出语言格式
          );
console.log(codeString,'codeString) 
********************
//输出
<span class="token keyword">function</span> <span class="token function">deepCopy</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> xxxx<span class="token punctuation">}</span>

一键复制实现 由于我们之前在plugin中设置了一键复制代码的功能开启,所以在静态的元素上增加如下关键词,在进行编译时Prism.js会自动帮我们在目标元素插入一个复制按钮,具体使用如下

//复制之后交互时间设置
data-prismjs-copy-timeout
//复制按钮默认展示文字
data-prismjs-copy
//复制按钮失败状态展示文字
data-prismjs-copy-error
//复制按成功状态展示文字
data-prismjs-copy-success

//实际使用代码
<body data-prismjs-copy-timeout="500">
	<pre><code class="language-c" data-prismjs-copy="Copy the C snippet!"
         data-prismjs-copy-error="Copy the error!"
          data-prismjs-success="Copy the success!"
        >int main() {
	return 0;
}</code></pre>
</body>

进阶使用

众所周知,chatgpt的回答不是一次性回答完毕的,是有一个过程,而且回答过程中有多少代码块都是未知的一切都是动态的所以这个静态的代码块渲染操作是不符合需求的。故另辟蹊径,拿到完整的返回答案之后进行正则匹配,将代码块逻辑截取出来然后进行Prism.js格式化,再将格式化的内容回填回去。

let htmlCopy="```function deepCopy(obj) { xxxx}```"
 let htmlArr = htmlCopy.split("```");
   htmlArr.map((item, index) => {
        if (index % 2 != 0) {
          let newTtem = Prism.highlight(
            item,
            Prism.languages.javascript,
            "javascript"
          );
          //此时为了保证代码块的处理
          // 进入队列是为了保证出队时候顺序无误展示顺序正确
          htmlArrTwo.push(newTtem);
        }
      });
      htmlArr.join(htmlArrTwo.shfit())

上面提到的一键复制功能同样是适用于静态代码块展示,因为是在编译阶段进行插入复制按钮,所以动态获取的实时展示字符串复制功能按钮无法添加上去。和上面实现思路差不多,在动态获取代码块内容之后进行组合加入复制按钮即可。

后话

以上就是这个五一假期,个人通过实现Prism.js+Vue3+vite仿照chatgpt实现代码块高亮功能的主要思路,如果大佬有更好用的思路欢迎在评论区进行讨论一起学习。

转载自:https://juejin.cn/post/7229636745577971770
评论
请登录