Vue系列-动态引入markdown文件并显示的完整实现案例
1. 安装html-loader与markdown-loadernpm i html-loader markdown-loader --save安装完成后可以在package.json中看到2. 配置md文件解析规则package.json同级的目录下找到vue.config.js,没有则新建一个,配置加载md文件的规则,如下module.exports = {//配置加载md文件时的解析规则ch
1. 安装html-loader与markdown-loader
npm i html-loader markdown-loader --save
安装完成后可以在package.json中看到
2. 配置md文件解析规则
package.json同级的目录下找到vue.config.js,没有则新建一个,配置加载md文件的规则,如下
module.exports = {
//配置加载md文件时的解析规则
chainWebpack: config => {
config.module
.rule('md')
.test(/\.md/)
.use('html-loader')
.loader('html-loader')
.end()
.use('markdown-loader')
.loader('markdown-loader')
.end()
}
}
3. 动态加载md文件并显示
下载vue-markdown
npm i vue-markdown -S
显示md文件:
<template>
<div>
<!--这里用的ElementUI中的button组件,点击显示md文件-->
<el-button @click="testMd">引入MD</el-button>
<!--引入vue-markdown组件-->
<vue-markdown :key="key">{{msg}}</vue-markdown>
</div>
</template>
<script>
import VueMarkdown from 'vue-markdown'
export default {
components:{
VueMarkdown
},
data(){
return{
//保存解析后的md文件对象
msg:'',
//为了让组件强制渲染
key: 0
}
},
methods:{
//必须设置为异步加载,因为解析需要时间,注意加上async
async testMd(){
var str= '测试.md'
//注意加上await ,运用import函数
await import('@/note/'+str).then(myModule => {
this.msg= myModule.default;
});
//强制重新渲染
this.key += 1
}
}
}
</script>
4. 几个注意的坑
4.1 import()函数的使用报错
使用import()异步引入文件路径时,如果是启用了ESLint的vue CLI项目的话,那么这样写就可能会得到一个报错
import’ and ‘export’ may only appear at the top level。
或者会报这样一个错误:
error Parsing error: Unexpected token import
解决办法是在.eslintrc.js添加这样3处,注意下面3处注释
module.exports = {
root: true, //此项是用来告诉eslint找当前配置文件不能往父级查找
"env": {
"browser": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
//1.添加parser
'parser': "babel-eslint",
"sourceType": "module",
//2.添加allowImportExportEverywhere
'allowImportExportEverywhere': true
},
"plugins": [
"vue"
],
rules: {
/*这里是eslint规则*/
//3.添加global-require
"global-require": 0//这里应该0代表off
}
}
4.2 组件渲染即时刷新
由于加载解析的md文件是异步的,所有组件会先渲染,故添加一个强制刷新的key,加载完成后强制+1即可,具体如下
<template>
<div>
<!-- 添加一个key属性 -->
<vue-markdown :key="key">{{msg}}</vue-markdown>
</div>
</template>
<script>
import VueMarkdown from 'vue-markdown'
export default {
components:{
VueMarkdown
},
data(){
return{
msg:'',
//key初始化
key: 0
}
},
methods:{
async testMd(){
var str= '测试.md'
await import('@/note/'+str).then(myModule => {
this.msg= myModule.default;
});
//强制重新渲染
this.key += 1
}
}
}
</script>
4.3 动态加载md路径,import()传入对象不能解析
我一开始是将整个路径作为对象传入,如下
错误版本:
...
var str= '测试.md'
//直接引入str对象
await import(str).then(myModule => {
this.msg= myModule.default;
});
...
通常编译的过程中会报这样一个错误:
Critical dependency: the request of a dependency is an expression
就是这个字符串变量编译不正确,这是由于webpack需要将所有import()的模块都进行单独打包,所以在工程打包阶段,webpack会进行依赖收集。此时,webpack会找到所有import()的调用,将传入的参数处理成一个正则,如:
import('./app'+path+'/util') => /^\.\/app.*\/util$/
因此在传路径的时候,一定不要将整个路径作为一个路径导入,应该用字符串组合形式代替
正确版本:
var str= '测试.md'
console.log(str)
//用字符串组合形式
await import('@/note/'+str).then(myModule => {
this.msg= myModule.default;
});
md文件图片保存应该放在相对路径
Typora写md文件时,应设置图片的相对路径,这样可以把md文件中链接的本地图片一并复制到项目目录中
具体实现见https://www.cnblogs.com/tian-ci/p/10543132.html
例如链接图片保存在./asserts中,最终可以一并将md文件与asserts文件夹复制到vue项目目录中,如下
这样加载md文件,图片链接就不会失效了。
5 最终效果
更多推荐
所有评论(0)