Vue系列-动态引入markdown文件并显示的完整实现案例

本文介绍如何在Vue项目中配置并动态加载Markdown文件,包括安装必要依赖、配置解析规则及使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 最终效果

在这里插入图片描述

### 配置 vue-markdown 组件以正确渲染代码块 为了使 `vue-markdown` 正确处理渲染 Markdown 文件中的代码块,需确保安装和配置过程无误。 #### 安装依赖包 通过 npm 或 yarn 来安装 `vue-markdown` 及其相关依赖项。对于本案例而言,除了 `vue-markdown` 外还需要考虑安全性和样式支持: ```bash npm install vue-markdown highlight.js --save ``` 这段命令不仅会下载 `vue-markdown` 这个核心库[^1],还会引入 `highlight.js` 用来高亮显示代码片段[^2]。 #### 导入 CSS 样式文件 为了让页面上的 markdown 渲染效果更佳,可以借助外部 CDN 提供的 GitHub Markdown 样式表来美化最终呈现的结果: ```html <link rel="stylesheet" href="https://cdn.bootcss.com/github-markdown-css/2.10.0/github-markdown.min.css"> ``` 此链接指向了一个托管于 BootCDN 的资源位置,它能有效提升用户体验的同时减少本地打包体积。 #### 修改 main.js 实现全局注册组件和服务 在项目的入口文件 `main.js` 中完成必要的初始化工作,包括但不限于加载自定义编辑器以及设置默认参数等操作: ```javascript import Vue from 'vue'; import App from './App.vue'; // 引入 vue-markdown 和语法高亮插件 import VueMarkdown from "vue-markdown"; import hljs from 'highlight.js'; Vue.component('vue-markdown', VueMarkdown); Vue.prototype.$hljs = hljs; new Vue({ render: h => h(App), }).$mount('#app'); ``` 上述 JavaScript 代码实现了对 `vue-markdown` 的全局注册,将 `highlight.js` 注册到 Vue 原型链上以便后续调用[^3]。 #### 自定义 vue-markdown 属性实现功能增强 最后,在实际使用的场景下可以通过传递特定属性给 `<vue-markdown>` 标签来自定义行为,比如开启 HTML 解析、启用 XHR 请求获取远程数据源等功能;同时利用 `$hljs.highlightBlock()` 方法手动触发代码着色逻辑,从而达到预期的效果: ```html <template> <div class="markdown-body"> <!-- 开启HTML解析 --> <vue-markdown :source="content" html></vue-markdown> </div> </template> <script> export default { data() { return { content: '# Hello World\n\nThis is a code block:\n\n```javascript\nconsole.log("test");\n```' }; }, mounted(){ this.$nextTick(() => { let blocks = document.querySelectorAll('pre code'); Array.prototype.forEach.call(blocks, (block) => { this.$hljs.highlightBlock(block); }); }) } }; </script> ``` 以上模板展示了如何结合前面提到的各项技术要点构建一个完整的解决方案,其中包含了基本结构搭建、事件监听机制设计等方面的知识点。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值