需求
- 引入 .md 文件后转化为html
- 标题添加锚点并生成 toc 目录
插件安装
文档
markdown-ithttps://markdown-it.docschina.org/ markdown-it-anchorhttps://www.npmjs.com/package/markdown-it-anchor markdown-it-toc-done-righthttps://www.npmjs.com/package/markdown-it-toc-done-right
安装
npm install markdown-it markdown-it-anchor markdown-it-toc-done-right html-loader highlight.js
配置
vue.config.js
// vue.config.js
module.exports = defineConfig({
// ...,
chainWebpack: (config) => {
config.module
.rule('md')
.test(/\.md$/)
.use('html-loader')
.loader('html-loader')
.end()
},
})
组件
<template>
<div>
<div v-highlight v-html="htmlContent"></div>
<div class="markdown-toc">
<h2>Table of Contents</h2>
<div ref="reference"></div>
</div>
</div>
</template>
<script>
import MarkdownIt from 'markdown-it'
import markdownItAnchor from 'markdown-it-anchor'
import markdownItTocDoneRight from 'markdown-it-toc-done-right'
import markdown from '../assets/md.md'
export default {
data() {
return {
htmlContent: '',
toc: [],
markdown: markdown
}
},
created() {
this.$nextTick(() => {
this.renderMarkdown()
})
},
methods: {
renderMarkdown() {
console.log(markdownItAnchor.permalink);
const that = this;
const md = new MarkdownIt().use(markdownItAnchor, {
permalink: markdownItAnchor.permalink.ariaHidden({
placement: 'after'
}),
permalinkBefore: false//这些有需要就去看文档吧
})
.use(markdownItTocDoneRight, {
containerClass: 'toc',//生成的容器的类名,这样最后返回来的字符串是 <nav class="toc"><nav/>
containerId: 'toc',//生成的容器的ID,这样最后返回来的字符串是 <nav id="toc"><nav/>
listType: 'ul',//导航列表使用ul还是ol
listClass: 'listClass',//li标签的样式名
linkClass: 'linkClass',//a标签的样式名
callback: function (html, ) {
//把目录单独列出来
that.$refs.reference.innerHTML = html;
}
})
const result = md.render(this.markdown)
// console.log(result);
this.htmlContent = result
console.log('md.options',md.options);
}}
}
</script>
<style scoped>
.markdown-toc {
margin-top: 20px;
}
</style>
样式优化
highlight.js
import Hljs from 'highlight.js'
import '../assets/style.css' // 代码高亮风格,选择更多风格需导入 node_modules/hightlight.js/styles/ 目录下其它css文件
const Highlight = {}
// 自定义插件
Highlight.install = function (Vue) {
// 自定义指令 v-highlight
Vue.directive('highlight', {
// 被绑定元素插入父节点时调用
inserted: function (el) {
const blocks = el.querySelectorAll('pre code')
for (let i = 0; i < blocks.length; i++) {
Hljs.highlightBlock(blocks[i])
}
},
// 指令所在组件的 VNode 及其子 VNode 全部更新后调用
componentUpdated: function (el) {
const blocks = el.querySelectorAll('pre code')
for (let i = 0; i < blocks.length; i++) {
Hljs.highlightBlock(blocks[i])
}
}
})
}
export default Highlight
main.js
import Highlight from './utils/highLight'
Vue.use(Highlight)