場景
今天忽然臨時接到一個需求:
就是將markdown檔案直接在vue專案中進行載入,並正常顯示出來。
這......,我知道是可以進行載入markdown檔案的。
但是我之前沒有做過,答覆的是:可以做的,但是這個需要一點時間。
領導:那行,你先調研一下。
簡單介紹 vue-markdown-loader
vue-markdown-loader可以將 Markdown 檔案轉換成Vue元件。
安裝 npm i vue-markdown-loader -D
步驟1:在vue.config.js檔案中去配置
module.exports = {
chainWebpack:config=>{
// 定義一個新的webpack模組規則,命名為md
config.module.rule('md')
// 透過.test()方法,指定這個規則應該匹配哪些檔案
// 這個規則將應用於所有以.md結尾的檔案,即Markdown檔案
.test(/\.md/)
// 使用vue-loader來處理Markdown檔案
.use('vue-loader')
.loader('vue-loader')
.end()
// 指定vue-markdown-loader來處理Markdown檔案
.use('vue-markdown-loader')
// 使用vue-markdown-loader包中的markdown-compiler模組來處理Markdown檔案
.loader('vue-markdown-loader/lib/markdown-compiler')
// raw: true以原始字串的形式處理Markdown內容,不進行HTML轉義等處理。
.options({
raw: true
})
}
}
哦豁-專案啟動報錯
遇見的問題1:SyntaxError: Unexpected token '??='
產生問題的原因:你的node版本是否太低。
在專案中驗證是否支援??=,可以驗證一下。太低的話升級版本就行
還有一種可能:less-loader或者sass-loader或者其他的包的版本不對。
遇見的問題2: Syntax Error: TypeError: Cannot read property ‘styles‘ of undefined
產生問題的原因:vue-loader的版本太高造成的。
我的專案是webpack的版本是:webpack5,它對應的vue-loader應該是vue-loader15,
我將它降級為:vue-loader@15
步驟2:在使用的頁面
<template>
<div>
<showMarkdown></showMarkdown>
</div>
</template>
<script>
// 引入的
import showMarkdown from './biji.md'
export default {
components:{
showMarkdown
},
data() {
return {
}
}
}
</script>
發現問題:最佳化樣式
我們需要下載 github-markdown-css
npm i github-markdown-css -S
這個是用來最佳化markdown展示出來的樣式
能夠保持與GitHub相同的視覺效果
在需要的檔案中引入 import 'github-markdown-css';
然後我們在元件的父級使用markdown-body這個類來美化markdown
<template>
<div>
<div class="markdown-body">
<showMarkdown></showMarkdown>
</div>
</div>
</template>
<script>
import 'github-markdown-css';
import showMarkdown from './biji.md'
export default {
components:{
showMarkdown
}
}
</script>
可以把markdown檔案在路由中引入嗎?
有的小夥伴說:既然我們能夠在頁面中引入當成元件,
那可以在路由檔案中引入嘛?
回答:可以的。下面我們就來看下
const routes = [
{
path: '/',
name: 'Home',
component: ()=>import("../views/echarts.vue")
},
{
path: '/xuexi',
name: 'xuexi',
component: ()=>import("../views/xuexi.vue")
},
{
path: '/md',
name: 'md',
// 引入的md檔案
component: ()=>import("../views/biji.md")
},
]
const router = new VueRouter({
mode: 'hash',
base: process.env.BASE_URL,
routes
})
main.js中引入 'github-markdown-css';
import Vue from 'vue'
import App from './App.vue'
import router from './router'
//全域性引入
import 'github-markdown-css';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
router,
render: h => h(App)
}).$mount('#app')
app.vue使用樣式
<template>
<div id="app" class="markdown-body">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/echarts">echarts</router-link> |
<router-link to="/art">art</router-link> |
<router-link to="/test">test</router-link> |
<router-link to="/xuexi">xuexi</router-link> |
</div>
<router-view/>
</div>
</template>
發現問題:markdown-body 汙染了全域性樣式
我們發現這樣整個專案中都有 markdown-body 這個類了。
這樣會影響其他元件的佈局樣式。
我們只想在引入的檔案是md才有這個樣式。
其他的檔案沒有這個樣式。
這個是否我們可以在app.vue檔案中判斷是否是md檔案。
如果是md檔案我們新增上markdown-body這個類,否則移除。
我們在路由檔案中的meta屬性來判斷是否是md檔案型別
路由檔案
const routes = [
{
path: '/md',
name: 'md',
component: ()=>import("../views/biji.md"),
meta:{
fileType:'md'
}
},
{
path: '/amd',
name: 'amd',
component: ()=>import("../views/amd.md"),
meta:{
fileType:'md'
}
}
]
app.vue
<template>
<div id="app" :class="componentPathName=='md' ? 'markdown-body' : null">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/echarts">echarts</router-link> |
<router-link to="/art">art</router-link> |
<router-link to="/test">test</router-link> |
<router-link to="/xuexi">xuexi</router-link> |
</div>
<router-view/>
</div>
</template>
<script>
export default {
computed: {
componentPathName () {
return this.$route.meta && this.$route.meta.fileType
}
},
}
</script>
md檔案內容有些時候是從服務端獲取的
上面我們渲染的都是本地的檔案.
如果 markdown 的內容是從服務端獲取的。
動態渲染怎麼去處理呢?
我們需要下載 vue-markdown
npm install vue-markdown --save
然後在vue.config.js檔案中去配置,與上面的配置相同(一樣的哈)
vue-markdown
它允許在Vue應用中輕鬆展示Markdown格式的內容。
它支援標準的Markdown語法。
如標題、列表、連結、圖片、程式碼塊等,並能夠將Markdown文字解析為HTML格式。
從而在Vue元件中展示。
vue-markdown 的簡單使用
<template>
<div>
<VueMarkdown>
{{ mdCont }}
</VueMarkdown>
</div>
</template>
<script>
import VueMarkdown from 'vue-markdown';
export default {
components:{
VueMarkdown
},
data() {
return{
mdCont:'#### 繪製一個矩形的思路我們這裡繪製矩形\n會使用到canvas.strokeRect(x,y, w, h)方法繪製一個描邊矩形![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/91e6190a5cdf4b548cbb7db766acb01c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR55qEZGl25Lii5LqG6IK_5LmI5Yqe:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMTMxMDI3MzU5MzQ0MDM5OCJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1733142556&x-orig-sign=Zghvt5lD2jYz6D0D0SaZye5cgos%3D)'
}
}
}
</script>
遠端請求的內容為啥渲染失敗
<template>
<div>
<VueMarkdown>
{{ mdCont }}
</VueMarkdown>
</div>
</template>
<script>
import VueMarkdown from 'vue-markdown';
export default {
components:{
VueMarkdown
},
data() {
return{
mdCont:'', //返回來的內容
showKey: '0',
}
},
created(){
this.serveAPi()
},
methods:{
serveAPi(){
setTimeout(() => {
this.mdCont = '#### 繪製一個矩形的思路我們這裡繪製矩形\n會使用到canvas.strokeRect(x,y, w, h)方法繪製一個描邊矩形![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/91e6190a5cdf4b548cbb7db766acb01c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR55qEZGl25Lii5LqG6IK_5LmI5Yqe:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMTMxMDI3MzU5MzQ0MDM5OCJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1733142556&x-orig-sign=Zghvt5lD2jYz6D0D0SaZye5cgos%3D)'
//更新設定這個key值
this.showKey = new Date().getTime()+ ''
},400)
}
},
}
</script>
我們發現md無法正常渲染,但是直接寫在data中的是可以渲染的。
說明返回來的資料,在渲染的時候元件沒有重新更新。
我們只需要使用key更新更新一下就行了。
遠端請求內容渲染markdown,key更新元件
<template>
<div>
<!-- 更新渲染這個元件,要不然返回來的資料無法正常渲染 -->
<VueMarkdown :key="showKey">
{{ mdCont }}
</VueMarkdown>
</div>
</template>
<script>
import VueMarkdown from 'vue-markdown';
export default {
components:{
VueMarkdown
},
data() {
return{
mdCont:'', //返回來的內容
showKey: '0',
}
},
created(){
this.serveAPi()
},
methods:{
serveAPi(){
setTimeout(() => {
this.mdCont = '#### 繪製一個矩形的思路我們這裡繪製矩形\n會使用到canvas.strokeRect(x,y, w, h)方法繪製一個描邊矩形![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/91e6190a5cdf4b548cbb7db766acb01c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5oiR55qEZGl25Lii5LqG6IK_5LmI5Yqe:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMTMxMDI3MzU5MzQ0MDM5OCJ9&rk3s=f64ab15b&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1733142556&x-orig-sign=Zghvt5lD2jYz6D0D0SaZye5cgos%3D)'
//更新設定這個key值
this.showKey = new Date().getTime()+ ''
},400)
}
},
}
</script>