前端解析markdown处理代码块高亮并添加复制功能实例代码

 更新时间:2025年11月12日 09:42:53   作者:yuan溜溜  
在Markdown中,原生语法并不直接支持文字高亮,不过你可以通过一些扩展的Markdown语法或者HTML标签来实现,这一效果这篇文章主要介绍了前端解析markdown处理代码块高亮并添加复制功能的相关资料,需要的朋友可以参考下

一、Marked.js简介与基本使用

Marked.js是一个轻量级的Markdown解析器,可以将Markdown文本快速转换为HTML。它易于使用且高度可定制。

基本使用方法

首先,安装引入Marked.js库:

npm i marked.js
import { Marked } from 'marked'

然后,使用简单的API进行转换:

// 解析Markdown文本
const markdownText = '# 标题\n\n这是一段**加粗**的文本。';
const htmlContent = marked.parse(markdownText);

二、实现代码语法高亮

虽然Marked.js可以解析代码块,但它本身不提供语法高亮功能。我们需要结合marked-highlight和Highlight.js来实现这一功能。

1. 引入Highlight.js和marked-highlight

marked-highlight是一个专门为Marked.js设计的扩展包,它需要配合highlight.js才能实现代码高亮功能。marked-highlight本身并不包含高亮逻辑,它只是提供了一个桥梁,让Marked.js能够方便地使用Highlight.js。

import { markedHighlight } from 'marked-highlight'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'

2. 配置Marked.js使用Highlight.js和markedHighlight

// 配置Marked.js
const marked = new Marked(
  markedHighlight({
    async: false, // 如果是异步的,可以设置为 true
    langPrefix: 'language-', // 可选:用于给代码块添加前缀
    highlight: code => {
      return hljs.highlightAuto(code).value
    },
  })
)

配置完成之后使用

<div v-html="markdown"></div>
const markdown = computed(() => marked.parse(mdStr))

效果如下:

三、获取语言类型以及添加代码复制功能

// 复制逻辑
const copyToClipboard = codeBlock => {
  const answer = codeBlock.textContent.trim()
  if (navigator.clipboard && navigator.clipboard.writeText) {
    return navigator.clipboard
      .writeText(answer)
      .then(() => {
        showSuccessToast('复制成功')
      })
  }
}
// 获取语言类型
const getLanguageCode = codeBlock => {
  const classList = codeBlock.className.split(' ')
  const langClass = classList.find(class => class.startsWith('language-'))
  if (langClass) {
    return langClass.replace('language-', '')
  }
  const parentClassList = codeBlock.parentNode.className.split(' ')
  const preLangClass = parentClassList.find(class => class.startsWith('language-'))
  if (preLangClass) {
    return preLangClass.replace('language-', '')
  }

  return null
}
// 添加复制按钮功能
const addCopyBtns = () => {
  nextTick(() => {
    const codeBlocks = document.querySelectorAll('pre code')
    codeBlocks.forEach(block => {
      if (block.parentNode.querySelector('.code-box')) {
        return
      }

      const parent = block.parentNode
      const codeBoxEle = document.createElement('div')
      codeBoxEle.className = 'code-box'
      const language = getLanguageCode(block)
      const langEle = document.createElement('span')
      langEle.className = 'code-lang'
      langEle.textContent = language || 'code'
      const copyButtonEle = document.createElement('div')
      copyButtonEle.className = 'copy-button'
      copyButtonEle.innerHTML = '复制'
      copyButtonEle.onclick = () => copyToClipboard(block)
      codeBoxEle.appendChild(langEle)
      codeBoxEle.appendChild(copyButtonEle)
      parent.classList.add('code-box')
      parent.appendChild(codeBoxEle)
    })
  })
}

ve3项目中使用(因为是流式输出,所以需要监听返回内容)

watch(markdown, newValue => {
  if (newValue) {
    nextTick(() => {
      addCopyBtns()
    })
  }
})
onMounted(() => {
  addCopyBtns()
})

效果如下

四、总结

Marked.js本身是一个纯JavaScript编写的Markdown解析器,因此它没有语言限制——它可以在任何支持JavaScript的环境中运行,通过结合Marked.js和Highlight.js,我们可以轻松实现Markdown文档的解析和代码高亮功能。添加复制按钮进一步提升了用户体验,让用户可以方便地获取代码片段。

对于react或者vue项目也可以使用其相应的开源方案,使用更加简洁,比如(需要的可以自行去了解)

Vue生态系统

  1. vue-markdown - 基于Marked.js的Vue组件
  2. @vuepress/markdown - VuePress使用的Markdown处理器
  3. vue-highlightjs - Vue的代码高亮指令
  4. element-plus - 提供ElCode组件用于代码展示

React生态系统

  1. react-markdown - 最流行的React Markdown渲染器
  2. react-syntax-highlighter - 功能强大的代码高亮组件
  3. highlight.js - 通用的代码高亮库
  4. @uiw/react-md-editor - 带编辑功能的Markdown组件

到此这篇关于前端解析markdown处理代码块高亮并添加复制功能的文章就介绍到这了,更多相关前端解析markdown代码块高亮内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 原生javascript和jquery判断浏览器版本等信息

    原生javascript和jquery判断浏览器版本等信息

    本文为大家详细介绍下通过jquery和原生javascript判断浏览器信息包括:判断浏览器是否为IE以及IE版本是多少等等,感兴趣的朋友可以参考下哈,希望对大家有所帮助
    2013-07-07
  • ES6扩展运算符和rest运算符用法实例分析

    ES6扩展运算符和rest运算符用法实例分析

    这篇文章主要介绍了ES6扩展运算符和rest运算符用法,结合实例形式分析了ES6扩展运算符和rest运算符基本功能、用法及操作注意事项,需要的朋友可以参考下
    2020-05-05
  • Typescript 实现函数重载的方式

    Typescript 实现函数重载的方式

    函数重载简单点说就是,同一个函数的不同实现方式,根据传入的参数的类型或者长度,决定最终调用哪一个实现,本文给大家介绍了Typescript 实现函数重载的方式,需要的朋友可以参考下
    2024-05-05
  • Bootstrap导航条学习使用(一)

    Bootstrap导航条学习使用(一)

    这篇文章主要为大家详细介绍了Bootstrap导航条的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • 通过flv.js播放监控示例深入探究直播流技术

    通过flv.js播放监控示例深入探究直播流技术

    本文记录一下在使用 flv.js 播放监控视频时踩过的各种各样的坑,虽然官网给的 Getting Started 只有短短几行代码,跑一个能播视频的 demo 很容易,但是播放时各种各样的异常会搞到你怀疑人生,下面我将自己踩过的坑,以及踩坑过程中补充的相关知识,详细总结一下
    2023-10-10
  • iscroll-probe实现下拉刷新和下拉加载效果

    iscroll-probe实现下拉刷新和下拉加载效果

    这篇文章主要为大家详细介绍了iscroll-probe下拉刷新和下拉加载,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • js实现把图片的绝对路径转为base64字符串、blob对象再上传

    js实现把图片的绝对路径转为base64字符串、blob对象再上传

    本文主要介绍了JavaScript把项目本地的图片或者图片的绝对路径转为base64字符串、blob对象再上传的方法,具有一定的参考价值,需要的朋友一起来看下吧
    2016-12-12
  • 微信WeixinJSBridge API使用实例

    微信WeixinJSBridge API使用实例

    这篇文章主要介绍了微信WeixinJSBridge API使用实例,本文直接给出HTML代码,代码中包含了很多实用功能,如图片预览、分享到微博、隐藏右上角按钮、获取网络状态、发起公众号微信支付等内容,需要的朋友可以参考下
    2015-05-05
  • JS实现漂亮的时间选择框效果

    JS实现漂亮的时间选择框效果

    这篇文章主要介绍了JS实现漂亮的时间选择框效果,结合实例形式分析了javascript时间选择框插件的实现与使用方法,需要的朋友可以参考下
    2016-08-08
  • 利用原生js和jQuery实现单选框的勾选和取消操作的方法

    利用原生js和jQuery实现单选框的勾选和取消操作的方法

    下面小编就为大家带来一篇利用原生js和jQuery实现单选框的勾选和取消操作的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09

最新评论