You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合Tailwind Typography与Highlight.js实现代码语法高亮

结合Marked.js与Highlight.js实现代码语法高亮(搭配Tailwind Typography)

我正在用Tailwind Typography优化HTML展示样式,想给包含<code>标签的代码块实现语法高亮。目前用Marked.js把Markdown转成HTML标签,请问怎么结合Highlight.js完成带高亮的HTML解析?以下是我当前的实现代码:

<script setup>
import { computed, watch } from "vue"
import { marked} from "marked";
import { markedHighlight } from "marked-highlight";
import hljs from 'highlight.js';


const props = defineProps({
  history: {
    type: Array,
    default: () => [],
    required: true,
  },
})
const processMarkdown = computed(()=>{
  return marked("Certainly! Here is an example of a simple JavaScript function that takes in a number and returns its square:

function square(num) {
return num * num;
}

console.log(square(5)); // Output: 25

In this code, the `square` function takes in a single argument called `num`, which is passed into the function as an argument. The function then multiplies the value of `num` by itself (i.e., `num * num`) and returns the result.

You can also define a function with multiple arguments like this:

function addMultipleNumbers(a, b, c) {
return a + b + c;
}

console.log(addMultipleNumbers(3, 4, 5)); // Output: 12

In this code, the `addMultipleNumbers` function takes in three arguments called `a`, `b`, and `c`. The function then adds all of these values together and returns the result.

You can also use a function to perform more complex operations, such as calculating the area of a circle or finding the factorial of a number. Here is an example of a JavaScript function that calculates the area of a circle:

function areaOfCircle(radius) {
return Math.PI * radius ** 2;
}

console.log(areaOfCircle(5)); // Output: 78.53981633974483

In this code, the `areaOfCircle` function takes in a single argument called `radius`, which is passed into the function as an argument. The function then uses the mathematical formula for the area of a circle (`Math.PI * radius ** 2`) to calculate the area of the circle and returns the result.

I hope these examples give you a better idea of how functions work in JavaScript! Let me know if you have any questions or need further clarification." , {
    highlight(md) {
      return hljs.highlightAll(md).value;
    }
  } )

  
})
watch(processMarkdown,(newValue) =>{
    hljs.highlightAll();
  })
const histories = computed(() => {
  console.log("History recompute")
  return props.history
})
</script>
<template>
  <div class="w-full h-full max-h-fit flex flex-col gap-2 overflow-auto">
    <div
      class="max-h-fit w-full bg-black flex flex-row"
      alt="container"
      v-for="(history, index) in histories"
      :key="index"
    >
      <div class="avatar p-3 pt-6 max-h-28">
        <div class="w-12 max-h-12 rounded">
          <img
            src="https://media.newyorker.com/photos/59095bb86552fa0be682d9d0/master/pass/Monkey-Selfie.jpg"
            alt=""
          />
        </div>
      </div>
      <div class="p-7 text-justify max-h-fit">
        <div>
          {{ history.request.content }}
        </div>
        <div v-if="history.response.content === ''">
          <span class="loading loading-ring loading-sm"></span>
        </div>
        <div v-else>
          <article class="prose">
            <div v-html=" marked.parse(history.response.content)"></div>
         
            <div v-html="processMarkdown"></div>
            {{console.log(processMarkdown)}}
          </article>
        </div>
      </div>
    </div>
  </div>
</template>

<style></style>

当前代码的问题

  1. 未正确使用markedHighlight插件集成Highlight.js,自定义的highlight函数写法错误
  2. 模板中存在重复解析Markdown的逻辑,同时使用了marked.parse和processMarkdown
  3. hljs.highlightAll()是用于批量渲染DOM中的代码块,不能直接处理字符串
  4. 未引入Highlight.js的样式文件,即使解析正确也看不到高亮效果

修正方案

1. 正确配置marked与highlight.js的集成

使用markedHighlight插件扩展marked,在配置中指定代码高亮的处理逻辑,同时支持指定语言的代码块。

2. 统一Markdown解析逻辑

封装解析函数,避免模板中直接调用marked.parse,保持代码整洁。

3. 移除冗余的watch监听

解析阶段已完成高亮处理,无需在watch中再次调用highlightAll。

4. 引入Highlight.js样式

必须导入高亮样式才能看到效果,可选择官方提供的任意样式。

完整修正代码

<script setup>
import { computed } from "vue"
import { marked } from "marked";
import { markedHighlight } from "marked-highlight";
import hljs from 'highlight.js';
// 导入Highlight.js样式,这里使用github风格,可替换为其他样式
import 'highlight.js/styles/github.css';

// 配置marked集成highlight.js
marked.use(markedHighlight({
  langPrefix: 'hljs language-',
  highlight(code, lang) {
    // 优先使用指定语言,不支持则自动检测或用纯文本
    const targetLang = hljs.getLanguage(lang) ? lang : 'plaintext';
    return hljs.highlight(code, { language: targetLang }).value;
  }
}))

const props = defineProps({
  history: {
    type: Array,
    default: () => [],
    required: true,
  },
})

// 封装Markdown解析函数
const parseMarkdown = (content) => {
  return marked(content);
}

const histories = computed(() => {
  console.log("History recompute")
  return props.history
})
</script>
<template>
  <div class="w-full h-full max-h-fit flex flex-col gap-2 overflow-auto">
    <div
      class="max-h-fit w-full bg-black flex flex-row"
      v-for="(history, index) in histories"
      :key="index"
    >
      <div class="avatar p-3 pt-6 max-h-28">
        <div class="w-12 max-h-12 rounded">
          <img
            src="https://media.newyorker.com/photos/59095bb86552fa0be682d9d0/master/pass/Monkey-Selfie.jpg"
            alt=""
          />
        </div>
      </div>
      <div class="p-7 text-justify max-h-fit">
        <div>
          {{ history.request.content }}
        </div>
        <div v-if="history.response.content === ''">
          <span class="loading loading-ring loading-sm"></span>
        </div>
        <div v-else>
          <article class="prose">
            <div v-html="parseMarkdown(history.response.content)"></div>
          </article>
        </div>
      </div>
    </div>
  </div>
</template>

<style></style>

补充说明

  • langPrefix配置确保生成的代码块标签带有hljs识别的类名,样式才能正确生效
  • 解析函数会自动处理带语言标识(如```js)和不带标识的代码块
  • Tailwind Typography的prose类会自动适配代码块的排版,与Highlight.js样式兼容

内容的提问来源于stack exchange,提问作者anina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:37:04