前端解析markdown處理代碼塊高亮并添加復(fù)制功能實(shí)例代碼
一、Marked.js簡(jiǎn)介與基本使用
Marked.js是一個(gè)輕量級(jí)的Markdown解析器,可以將Markdown文本快速轉(zhuǎn)換為HTML。它易于使用且高度可定制。
基本使用方法
首先,安裝引入Marked.js庫(kù):
npm i marked.js
import { Marked } from 'marked'
然后,使用簡(jiǎn)單的API進(jìn)行轉(zhuǎn)換:
// 解析Markdown文本 const markdownText = '# 標(biāo)題\n\n這是一段**加粗**的文本。'; const htmlContent = marked.parse(markdownText);
二、實(shí)現(xiàn)代碼語(yǔ)法高亮
雖然Marked.js可以解析代碼塊,但它本身不提供語(yǔ)法高亮功能。我們需要結(jié)合marked-highlight和Highlight.js來(lái)實(shí)現(xiàn)這一功能。
1. 引入Highlight.js和marked-highlight
marked-highlight是一個(gè)專門為Marked.js設(shè)計(jì)的擴(kuò)展包,它需要配合highlight.js才能實(shí)現(xiàn)代碼高亮功能。marked-highlight本身并不包含高亮邏輯,它只是提供了一個(gè)橋梁,讓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, // 如果是異步的,可以設(shè)置為 true
langPrefix: 'language-', // 可選:用于給代碼塊添加前綴
highlight: code => {
return hljs.highlightAuto(code).value
},
})
)
配置完成之后使用
<div v-html="markdown"></div> const markdown = computed(() => marked.parse(mdStr))
效果如下:

三、獲取語(yǔ)言類型以及添加代碼復(fù)制功能
// 復(fù)制邏輯
const copyToClipboard = codeBlock => {
const answer = codeBlock.textContent.trim()
if (navigator.clipboard && navigator.clipboard.writeText) {
return navigator.clipboard
.writeText(answer)
.then(() => {
showSuccessToast('復(fù)制成功')
})
}
}
// 獲取語(yǔ)言類型
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
}
// 添加復(fù)制按鈕功能
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 = '復(fù)制'
copyButtonEle.onclick = () => copyToClipboard(block)
codeBoxEle.appendChild(langEle)
codeBoxEle.appendChild(copyButtonEle)
parent.classList.add('code-box')
parent.appendChild(codeBoxEle)
})
})
}
ve3項(xiàng)目中使用(因?yàn)槭橇魇捷敵?,所以需要監(jiān)聽(tīng)返回內(nèi)容)
watch(markdown, newValue => {
if (newValue) {
nextTick(() => {
addCopyBtns()
})
}
})
onMounted(() => {
addCopyBtns()
})
效果如下

四、總結(jié)
Marked.js本身是一個(gè)純JavaScript編寫的Markdown解析器,因此它沒(méi)有語(yǔ)言限制——它可以在任何支持JavaScript的環(huán)境中運(yùn)行,通過(guò)結(jié)合Marked.js和Highlight.js,我們可以輕松實(shí)現(xiàn)Markdown文檔的解析和代碼高亮功能。添加復(fù)制按鈕進(jìn)一步提升了用戶體驗(yàn),讓用戶可以方便地獲取代碼片段。
對(duì)于react或者vue項(xiàng)目也可以使用其相應(yīng)的開(kāi)源方案,使用更加簡(jiǎn)潔,比如(需要的可以自行去了解)
Vue生態(tài)系統(tǒng)
- vue-markdown - 基于Marked.js的Vue組件
- @vuepress/markdown - VuePress使用的Markdown處理器
- vue-highlightjs - Vue的代碼高亮指令
- element-plus - 提供ElCode組件用于代碼展示
React生態(tài)系統(tǒng)
- react-markdown - 最流行的React Markdown渲染器
- react-syntax-highlighter - 功能強(qiáng)大的代碼高亮組件
- highlight.js - 通用的代碼高亮庫(kù)
- @uiw/react-md-editor - 帶編輯功能的Markdown組件
到此這篇關(guān)于前端解析markdown處理代碼塊高亮并添加復(fù)制功能的文章就介紹到這了,更多相關(guān)前端解析markdown代碼塊高亮內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ES6擴(kuò)展運(yùn)算符和rest運(yùn)算符用法實(shí)例分析
這篇文章主要介紹了ES6擴(kuò)展運(yùn)算符和rest運(yùn)算符用法,結(jié)合實(shí)例形式分析了ES6擴(kuò)展運(yùn)算符和rest運(yùn)算符基本功能、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-05-05
Typescript 實(shí)現(xiàn)函數(shù)重載的方式
函數(shù)重載簡(jiǎn)單點(diǎn)說(shuō)就是,同一個(gè)函數(shù)的不同實(shí)現(xiàn)方式,根據(jù)傳入的參數(shù)的類型或者長(zhǎng)度,決定最終調(diào)用哪一個(gè)實(shí)現(xiàn),本文給大家介紹了Typescript 實(shí)現(xiàn)函數(shù)重載的方式,需要的朋友可以參考下2024-05-05
Bootstrap導(dǎo)航條學(xué)習(xí)使用(一)
這篇文章主要為大家詳細(xì)介紹了Bootstrap導(dǎo)航條的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
通過(guò)flv.js播放監(jiān)控示例深入探究直播流技術(shù)
本文記錄一下在使用 flv.js 播放監(jiān)控視頻時(shí)踩過(guò)的各種各樣的坑,雖然官網(wǎng)給的?Getting Started?只有短短幾行代碼,跑一個(gè)能播視頻的 demo 很容易,但是播放時(shí)各種各樣的異常會(huì)搞到你懷疑人生,下面我將自己踩過(guò)的坑,以及踩坑過(guò)程中補(bǔ)充的相關(guān)知識(shí),詳細(xì)總結(jié)一下2023-10-10
iscroll-probe實(shí)現(xiàn)下拉刷新和下拉加載效果
這篇文章主要為大家詳細(xì)介紹了iscroll-probe下拉刷新和下拉加載,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
js實(shí)現(xiàn)把圖片的絕對(duì)路徑轉(zhuǎn)為base64字符串、blob對(duì)象再上傳
本文主要介紹了JavaScript把項(xiàng)目本地的圖片或者圖片的絕對(duì)路徑轉(zhuǎn)為base64字符串、blob對(duì)象再上傳的方法,具有一定的參考價(jià)值,需要的朋友一起來(lái)看下吧2016-12-12
JS實(shí)現(xiàn)漂亮的時(shí)間選擇框效果
這篇文章主要介紹了JS實(shí)現(xiàn)漂亮的時(shí)間選擇框效果,結(jié)合實(shí)例形式分析了javascript時(shí)間選擇框插件的實(shí)現(xiàn)與使用方法,需要的朋友可以參考下2016-08-08
利用原生js和jQuery實(shí)現(xiàn)單選框的勾選和取消操作的方法
下面小編就為大家?guī)?lái)一篇利用原生js和jQuery實(shí)現(xiàn)單選框的勾選和取消操作的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09

