• [md-loader]使用md来编写vue组件库文档


    需求场景:

    • 当前项目公共组件比较多,需要一个文档来描述
    • 希望轻量化,没有额外资源部署一个文档项目,即内嵌在开发项目中

    期望效果

    一个md文件一个页面
    在这里插入图片描述

    生成如下,并且一个md文件可以同时写多个demo在这里插入图片描述

    思路来源

    使用 element-ui源码中的md-loader,抽取出来后,增强一些其他功能即可。
    其中重点是实现md文件中的 :::demovuepress·也是这个思路。
    根据 :::demo 将 md文件中的vue片段用 demo-block 组件包裹,然后传递给 vue-loader生成html 即可。

    demo-block 组件是自己定义的一个vue组件容器,可在源码中找到。

    过程

    代码准备

    1. 将element-ui 中的 md-loader 拷贝到自己项目中.
    2. 安装所需要的依赖
    "markdown-it": "^13.0.1",
    "markdown-it-anchor": "^8.6.4",
    "markdown-it-chain": "^1.3.0",
    "markdown-it-container": "^3.0.0",
    "transliteration": "^2.3.5",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 配置md文件的loader
    // vue.config.js
     chainWebpack: (config) => {
        // 使用自定义 loader
        config.module
          .rule("md-loader")
          .test(/\.md$/)
          .use("vue-loader")
          .loader("vue-loader")
          .end()
          .use("md-loader")
          .loader(path.join(__dirname, "./md-loader/index.js"))
          .end();
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 准备好文件页面用到的初始组件,具体可以参考element-ui以及我的demo源码在这里插入图片描述
    2. 因为我的与 element-ui 一样使用的是路由切换页面的,所以配置了动态路由
    import Vue from "vue";
    import VueRouter from "vue-router";
    
    Vue.use(VueRouter);
    import Guide from "@/components/.components/Guide.vue";
    // const routes = [{ path: "/", component: Guide }];
    const routes = [
      { path: "/", redirect: "/fe/changelog" },
      { path: "/fe/:name", component: Guide },
    ];
    
    const router = new VueRouter({
      routes,
    });
    
    export default router;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    最后直接重新运行即可。

    增强

    md中的css直接作用于页面

    由于element-ui 的文档中的css是单独写在文件中的,在md中的css并不会作用于页面,那么我是做了一点修改。

    解析出demo中的css后,统一加入 style 标签中。
    md-loader\index.js
    在这里插入图片描述

    在这里插入图片描述
    当前只实现了匹配普通style,如果需要匹配 lang=“less” ,只要修改下匹配style的正则即可。

    // util.js
    function stripStyle(content) {
      const result = content.match(/<(style)\s*([\s\S]+)<\/\1>/);
      return result && result[2] ? result[2].trim() : "";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    组件注册

    首先是 md文件的注册

    // src\components\.components\Guide.vue
    <script>
    import navsData from './nav.config.js'
    import SideNav from './SideNav.vue'
    const requireComponents = require.context('../docs/', false, /\.md/)
    const loadDocsComponents = {}
    requireComponents.keys().forEach(fileName => {
        // 组件实例
        const reqCom = requireComponents(fileName)
        // 截取路径作为组件名
        const reqComName = fileName.replace(/\.\//, '').replace(/\.md/, '')
        // 组件挂载
        loadDocsComponents['md-' + reqComName] = reqCom.default || reqCom
    })
    export default {
        components: { SideNav, ...loadDocsComponents }
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    其次是项目公共文件的注册。由于公共组件是内嵌到 demo-block 组件中,所以只能选择全局注册,但是注册入口不选择在 main.js。 选中在 src\components\.components\Guide.vue

    // src\components\.components\Guide.vue
    import Vue from 'vue'
    const components = require.context('../', false, /\.vue/)
    components.keys().forEach(fileName => {
        // 组件实例
        const reqCom = components(fileName)
        // 截取路径作为组件名
        const reqComName = fileName.replace(/\.\//, '').replace(/\.vue/, '')
        // 组件挂载
        Vue.component(reqComName, reqCom.default || reqCom)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其他问题

    如果发现一些奇怪的报错,可以优先排查版本依赖兼容问题。

    参考

    本次例子的源码
    element-ui的文档源码
    若川视野 ElementUI 组件库 md-loader 的解析和优化
    倪凡 Element-UI源码阅读之md显示到页面

  • 相关阅读:
    PMP的智慧(2) - 系统性思考及复杂性
    深度学习——LSTM基础
    维格云筛选组件入门教程
    DRU-Net--一种用于医学图像分割的高效深度卷积神经网络
    用人工智能压缩视频的尝试
    如何基于香橙派AIpro对视频/图像数据进行预处理
    非全自研可视化表达引擎RuleLinK可视化之路
    数据导入与预处理-第6章-03数据规约
    OSPF高等特性——Forwarding Address
    docker&kubernets篇(十二)
  • 原文地址:https://blog.csdn.net/qq_39211165/article/details/126570995