正在造一個的中後臺框架輪子 e-admin ,文檔與開發同步進行。
文檔部分涉及了markdown
解析,剛開始是嘗試使用現成庫 vue-markdown-loader,可是代碼高亮部分很差定製處理,遂放棄。
第一次嘗試自已寫個loader
,出乎意料的簡單。markdown
解析使用的是hyperdown;
代碼高亮經過prismjs實現;
代碼高亮部分剛開始是嘗試用highlight.js可是不知爲什麼JavaScript
第一行的格式化會出現異常,用prismjs則無此問題。
首先安裝依賴javascript
npm install hyperdown prismjs -D
markdown-loader.js
css
const HyperDown = require('hyperdown'); const Prism = require('prismjs'); function markdownLoader(val) { let parser = new HyperDown(); let html = parser.makeHtml(val); html = html.replace(/(?<=<pre><code[^>]*?>)[\s\S]*?(?=<\/code><\/pre>)/gi, v => { v = v.replace(/_&/g, ' ').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); return Prism.highlight(v, Prism.languages.javascript); }); return ( `<template><div class="markdown">${html}</div></template>` ); } module.exports = markdownLoader;
項目使用的是vue-cli 3.x
,在vue.config.js
添加如下配置html
module.exports = { configureWebpack: config => { config.module.rules.push({ test: /\.md$/, use: [ { loader: 'vue-loader', }, { loader: require.resolve('./markdown-loader'), }, ], }, ); }, };
在入口文件main.js
導入prismjs
樣式vue
import 'prismjs/themes/prism.css';
如今能夠把.md
文件當成vue組件來使用了test.md
java
test.vue
git
<template> <test-md></test-md> </template> <script> import testMd from './test.md'; export default { components: {testMd},
md組件效果
github
固然也能夠做爲路由組件來使用,最終實現以下預期效果vue-cli
自擼loader
的另外一個好處就是自由度高,咱們能夠隨意擴展功能,好比既然md
文件被解析成vue組件,由於文檔一般都伴隨着實例,若是能在裏面md
裏面插入slot
在使用中咱們隨意在插槽中插入實例,那可太方便了,實現起來也就是一個正則的事npm
function markdownLoader(val) { let parser = new HyperDown(); let html = parser.makeHtml(val); html = html.replace(/(?<=<pre><code[^>]*?>)[\s\S]*?(?=<\/code><\/pre>)/gi, v => { v = v.replace(/_&/g, ' ').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); return Prism.highlight(v, Prism.languages.javascript); }); // 解析slot轉換爲正常標籤 html = html.replace(/<slot[\s\S]*?><\/slot>/gi, v => { v = v.replace(/_&/g, ' ').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&'); return v; }); return ( `<template><div class="markdown">${html}</div></template>` ); }
如今咱們能夠在md文件裏面直接寫slot
插槽了test-slot.md
markdown
#擴展 slot ###default 這裏插入一個默認插槽 <slot></slot> ####footer 這裏插入一個具名插槽 <slot name="footer"></slot>
在咱們實例中使用這個組件試試效果
<template> <test-slot> <el-button type="primary">default</el-button> <template v-slot:footer> <el-button type="success">footer</el-button> </template> </test-slot> </template> <script> import testSlot from './test-slot.md' export default { components: { testSlot },
運行 done
添加一個錨點id解析方案
/** * id解析方案 * markdown ###(#item-1)標題 * html <h3 id="item-1">標題</> * @type {string} */ html = html.replace(/>\(#[\s\S]*?\)/gi, v => { const id = v.substr(3, v.length - 4); return ` id="${id}">`; });
這段代碼插入到上面函數的return
以前,就能夠把(#item-1)
解析成當前標籤的id id = "item-1"
,效果是有的,可是由於這種寫法不是markdown
規範,因此慎用吧
以這篇文章的內容爲基礎搭建的 e-admin中文文檔