Vue项目如何根据路由参数动态导入markdown文件?
问题原因
- 路径拼接错误:你给出的目录结构中md文件直接存放在
src/posts/下,没有二级blog目录,拼接路径时多写了/blog层级;同时你的组件放在src/view/目录下,你写的相对路径是从组件位置出发查找src/view/posts/,和实际存放md的src/posts/路径不匹配。 - webpack动态require限制:webpack编译阶段需要确定可能加载的文件范围,完全动态的路径无法被webpack识别,需要给出固定的路径前缀让webpack提前把对应目录下的md文件纳入编译范围。
- 多余的marked调用:你已经配置了
markdown-loader+html-loader,导入的md文件会直接被转换为可直接使用的HTML字符串,不需要再手动调用marked做转换。 - CopyWebpackPlugin运行时机问题:这个插件只会在
build阶段执行文件复制,serve阶段开发服务器是从内存读取文件,不会执行复制操作,也不会默认把src下的目录暴露为静态路由,所以你直接访问/posts路径无法找到对应文件。
修复方案
方案一:编译时打包md文件(适合博客文章数量不多的场景)
直接通过webpack把所有md文件编译进产物包,不用请求静态资源:
- 修正组件导入逻辑
<template> <div v-html="md"></div> </template> <script> export default { data () { return { md: undefined, }; }, created () { // 固定路径前缀让webpack识别,编译时会把src/posts下所有md都纳入打包范围 const md = require(`../posts/${this.$route.params.postName}.md`); this.md = md; }, }; </script>
- 移除冗余配置:该方案不需要用到CopyWebpackPlugin,直接把webpack配置里的CopyPlugin相关代码删除即可。
方案二:运行时请求静态md文件(适合博客文章数量多,不想打包进主bundle的场景)
- 保留CopyWebpackPlugin配置,同时在vue.config.js中添加devServer配置,让开发环境也能访问到posts目录下的静态文件:
const path = require('path') module.exports = { configureWebpack: { // 保留你原来的markdown-loader规则和CopyPlugin配置 }, devServer: { static: { directory: path.join(__dirname, 'src/posts'), publicPath: '/posts' } } }
- 修正组件逻辑,改成axios请求静态md文件后再转换:
<template> <div v-html="md"></div> </template> <script> import axios from 'axios' import marked from "marked"; export default { data () { return { md: undefined, }; }, async created () { const res = await axios.get(`/posts/${this.$route.params.postName}.md`) this.md = marked(res.data) }, }; </script>
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

