vue highlight.js插件代码高亮卡顿

196 阅读1分钟

vue highlight.js插件代码高亮卡顿

  updated() {
    let that = this;
    this.$nextTick(() => {
      // 获取所有标签code
      const code = document.querySelectorAll("pre");
      if (code.length == 0) return;
      // 根据循环发送code
      for (let i = 0; i < code.length; i++) {
        // 定义worker
        const workerUrl = URL.createObjectURL(
          new Blob(
            [
              `
            onmessage = (event) => {
            importScripts('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js');
            const result = self.hljs.highlightAuto(event.data.textContent);
              let parms = {
                textContent:result.value,
                index:event.data.index
              }
            postMessage(parms);
          }
            `,
            ],
            { type: "application/javascript" }
          )
        );
        const worker = new Worker(workerUrl);
        let obj = {
          textContent: code[i].textContent,
          index: i,
        };
        // 发送到worker
        worker.postMessage(obj);
        worker.onmessage = (event) => {
          // 创建一个新的Web Worker实例
          this.$nextTick(() => {
            let newDiv;
            // 接收worker
            code[event.data.index].innerHTML = event.data.textContent;
            // 获取code标签
            const preElement = code[i];
            // 获取code标签的父元素
            const parentElement = preElement.parentNode;
            // 获取parentElement下的第一个div元素
            const firstDiv = parentElement.querySelector("div");
            // 检查是否找到了div元素
            if (!firstDiv) {
              // 创建一个div
              newDiv = document.createElement("div");
              // 给div添加文字内容
              newDiv.innerText = "复制代码";
              // 给div设置class样式
              newDiv.setAttribute("class", "copyButton");
              // 把div插入到code标签前面
              parentElement.insertBefore(newDiv, preElement);
              // 给div添加点击事件
              newDiv.onclick = function () {
                const textArea = document.createElement("textarea");
                textArea.value = preElement.innerText;
                document.body.appendChild(textArea);
                textArea.select();
                document.execCommand("copy");
                document.body.removeChild(textArea);
                that.$message.success('复制成功');
              };
            }
          });
          worker.terminate();
        };
      }
    });
  },

这是我目前写的 我个人感觉很乱 如果看到有更好的 可以 留言 官网这个插件是支持webWorker的 但是我直接引入会报错 所以写成这样没报错的 我放在updata是因为我做的ai聊天 需要流式输出 所以我放到了 updata这个 大家按情况 自行选择