企业项目中md-loader项目组件文档实现

news2024/10/5 15:35:32

背景需求:

随着业务增多,公共组件变多,无法直观知道其中的方法使用和业务场景,轻量级不需要重新新建一个项目

技术基础:

1.仿造element-ui md-loader

需求场景:

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

期望效果

一个md文件一个页面

生成如下,并且一个md文件可以同时写多个demo

思路来源

使用 element-ui源码中的md-loader,抽取出来后,增强一些其他功能即可。

其中重点是实现md文件中的 :::demo ,vuepress·也是这个思路。

根据 :::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. 配置md文件的loader

// vue.config.js

chainWebpack: config => {
    // 移除 prefetch 插件
    config.plugins.delete("preload");
    config.plugins.delete("prefetch");
    // 自定义插件
    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. 准备好文件页面用到的初始组件,具体可以参考element-ui
  2. 因为我的与 element-ui 一样使用的是路由切换页面的,所以配置了动态路由

import Vue from "vue";

import VueRouter from "vue-router";

export default [
  {
    name: "更新日志",
    path: "/changelog",
  },
  {
    name: "开发规范",
    children: [
      {
        path: "/git",
        name: "代码提交规范",
      },
      {
        path: "/docs-rule",
        name: "文档编写规范",
      },
    ],
  },
  {
    name: "components组件",
    groups: [
      {
        groupName: "form",
        list: [
          {
            path: "/s_basicType",
            title: "BasicType 数据类型",
          },
          {
            path: "/s_calculationStatus",
            title: "CalculationStatus 重算状态",
          },
          {
            path: "/s_dataDimension",
            title: "DataDimension 数据来源",
          },
          {
            path: "/s_employingUnit",
            title: "EmployingUnit 用工单位通用",
          },
          {
            path: "/s_employingUnitBind",
            title: "EmployingUnitBind 用工单位通用",
          }
        ],
      },
      {
        groupName: "业务组件",
        list: [
          {
            path: "/s_upload",
            title: "Upload 上传图片",
          },
          {
            path: "/s_calculationStatus",
            title: "业务组件2",
          },
          {
            path: "/s_dataDimension",
            title: "业务组件3",
          },
          {
            path: "/s_employingUnit2",
            title: "业务组件4"
          }
        ],
      }
    ]
  },
  {
    name: "Element官网",
    href: "https://element.eleme.cn/#/zh-CN/component/installation",
  },
  {
    name: "xxxUI官网",
    href: "http://xx.xx.xx:8080/#/zh-CN/",
  },
  {
    name: "Iconfont官网",
    href: "https://www.iconfont.cn/",
  },
  {
    name: "Vue官网",
    href: "https://cn.vuejs.org/",
  }
];

最后直接重新运行即可。

增强

md中的css直接作用于页面

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

解析出demo中的css后,统一加入 style 标签中。

md-loader\index.js

const {
  stripScript,
  stripTemplate,
  genInlineComponentText,
  stripStyle
} = require("./util");
const md = require("./config");


module.exports = function(source) {
  const content = md.render(source);
  const startTag = "<!--element-demo:";
  const startTagLen = startTag.length;
  const endTag = ":element-demo-->";
  const endTagLen = endTag.length;
  let componenetsString = "";
  let id = 0; // demo 的 id
  const output = []; // 输出的内容
  let start = 0; // 字符串开始位置


  let commentStart = content.indexOf(startTag);
  let commentEnd = content.indexOf(endTag, commentStart + startTagLen);
  const styleList = [];
  while (commentStart !== -1 && commentEnd !== -1) {
    output.push(content.slice(start, commentStart));


    const commentContent = content.slice(
      commentStart + startTagLen,
      commentEnd
    );
    const html = stripTemplate(commentContent);
    const script = stripScript(commentContent);


    const style = stripStyle(commentContent);
    styleList.push(`<style>${style}</style>`);
    const demoComponentContent = genInlineComponentText(html, script);
    const demoComponentName = `element-demo${id}`;
    output.push(
      `<template slot="source"><${demoComponentName} class="${demoComponentName}"/></template>`
    );
    componenetsString += `${JSON.stringify(
      demoComponentName
    )}: ${demoComponentContent},`;


    // 重新计算下一次的位置
    id++;
    start = commentEnd + endTagLen;
    commentStart = content.indexOf(startTag, start);
    commentEnd = content.indexOf(endTag, commentStart + startTagLen);
  }


  // 仅允许在 demo 不存在时,才可以在 Markdown 中写 script 标签
  // todo: 优化这段逻辑
  let pageScript = "";
  if (componenetsString) {
    pageScript = `<script>
      export default {
        name: 'component-doc',
        components: {
          ${componenetsString}
        }
      }
    </script>`;
  } else if (content.indexOf("<script>") === 0) {
    // 硬编码,有待改善
    start = content.indexOf("</script>") + "</script>".length;
    pageScript = content.slice(0, start);
  }


  output.push(content.slice(start));
  return `
    <template>
      <section class="content element-doc">
        ${output.join("")}
      </section>
    </template>
    ${pageScript}
   ${styleList}
  `;
};

当前只实现了匹配普通style,如果需要匹配 lang=“scss” ,只要修改下匹配style的正则即可。

组件注册

首先是 md文件的注册

// src\components\.components\Guide.vue

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

// src\components\.components\Guide.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)
})

saas-risk-admin实施效果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/825987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在AndroidStudio中如何查看Gradle的版本

以Android Studio Giraffe | 2022.3.1为例 File -> Project Structure -> Project Android Gradle Plugin Version - Android Gradle插件版本号 Gradle Version - Gradle的版本号 Gradle 版本 (gradle version): Gradle 是一种通用的构建工具&#xff0c;用于构建各种类…

蓝牙、GPS定位学习

启动状态&#xff08;APP&#xff09; 冷启动 指在启动应用时&#xff0c;后台没有应用的进程或者进程被杀死的情况下&#xff0c;系统会重新创建一个新的进程&#xff0c;并按照一定的顺序创建和初始化Application类和MainActivity类&#xff0c;最后显示在界面上。这个过程需…

vue3使用iframe引入其他网站,vue-router路由跳转后页面空白,刷新之后才展示页面内容乌龙事件

问题描述&#xff1a;vue3项目的页面A跳转到页面B时&#xff0c;页面B页面是空白的&#xff0c;需要手动刷新一下才能恢复正常&#xff0c;在页面A中用iframe引入了别的网站&#xff08;后续事实证明&#xff0c;跟iframe没一毛钱的关系&#xff09;。着急的童鞋可以直接拉到底…

【C++】开源:Eigen3矩阵与线性代数库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Eigen3矩阵与线性代数库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

机柜PDU的选购也有大学问——与机柜PDU相关的那些事儿

在各行各业数据中心机房供配电建设过程中&#xff0c;机柜专用PDU电源插座看似是一个较为简单的用电设备&#xff0c;事实上又不那么简单。机柜PDU&#xff0c;是为安装在机柜内部的IT设备提供电源分配、管理的末端配电设备&#xff0c;在不同的工作场合对于PDU的规格要求也是不…

HackSudo2靶机 通关详解

环境配置 发现vmWare的kali扫不到virtualbox的靶机 网上找了挺久资料都没解决 索性全桥接上物理机了 信息收集 漏洞发现 扫个目录 都看了一眼 没什么有用的 然后回到file.php 感觉之前做过类似的靶场,猜测存在文件包含 随便传个file试试 确实有 考虑日志文件包含 之前看…

C++---list常用接口和模拟实现

list---模拟实现 list的简介list函数的使用构造函数迭代器的使用list的capacitylist element accesslist modifiers list的模拟实现构造函数&#xff0c;拷贝构造函数和迭代器begin和endinsert和eraseclear和析构函数 源码 list的简介 list是用双向带头联表实现的一个容器&…

[用go实现解释器]笔记1-词法分析

本文是《用go实现解释器》的读书笔记 ​ https://malred-blog​malred.github.io/2023/06/03/ji-suan-ji-li-lun-ji-shu-ji/shi-ti/go-compile/yong-go-yu-yan-shi-xian-jie-shi-qi/go-compiler-1/#toc-heading-6http://个人博客该笔记地址 ​github.com/malred/malanghttp:/…

入行软件测试的一些工作感悟

成为xx一员测试已经有1年半了&#xff0c;一直没有真正坐下来花些时间将自己的思路理清一下。刚好近期公司落地了OKR&#xff0c;给自己制定了OKR之后思路终于开始清晰起来&#xff0c;朦朦胧胧地开始看清了远方的路&#xff0c;麻着胆子分析一下自己&#xff0c;毕竟摸黑走路的…

Screens 4 for mac VNC客户端 强大的远程控制工具

Screens 4 for Mac 是一款功能强大的 VNC 客户端软件&#xff0c;为 Mac 用户提供了便捷的远程访问和控制解决方案。无论您是需要远程管理服务器、办公电脑&#xff0c;还是需要远程协助他人解决问题&#xff0c;Screens 4 都是您的理想选择。 Screens 4 for Mac具备简洁直观的…

小白到运维工程师自学之路 第六十二集 (docker持久化与数据卷容器)

一、概述 Docker持久化是指将容器中的数据持久保存在主机上&#xff0c;以便在容器重新启动或迁移时不丢失数据。由于Docker容器是临时和可变的&#xff0c;它们的文件系统默认是易失的&#xff0c;这意味着容器中的任何更改或创建的文件都只存在于此容器的生命周期内。但是&a…

基于低代码平台快速搭建应用

一、前言 近年来&#xff0c;SaaS行业的迅猛发展带动了低代码领域的快速兴起。国外的低代码创业公司如Mendix、Outsystems&#xff0c;以及国内的软件业巨头如华为、用友、金蝶等和小众高性价比的引迈JNPF都已经纷纷涉足低代码市场。根据Transparency Market Research的报告&am…

独立站运营要做哪些工作?包含哪些模块?

在电商行业中&#xff0c;广告投放和设计等岗位的招聘可能会相对容易&#xff0c;但真正理解并有效执行独立站运营的人员却十分稀少。因此&#xff0c;今天将聚焦于独立站的运营&#xff0c;特别是针对精品垂直站和品牌站的运营。 首先&#xff0c;我们需要了解“运营”的含义…

vue2使用v-viewer实现图片预览

v-viewer 用于图片浏览的Vue组件&#xff0c;支持旋转、缩放、翻转等操作&#xff0c;基于viewer.js。 中文文档&#xff1a;Vue图片浏览组件v-viewer&#xff0c;支持旋转、缩放、翻转等操作 | Mirari’s Blog 代码示例&#xff1a;https://mirari.cc/v-viewer/ 在Vue.js 2…

Java并发系列之三:乐观锁机制

上一篇悲观锁中&#xff0c;我们讲到悲观锁的四种状态时&#xff0c;提到了“无锁”这种状态&#xff0c;并解释其有两种语义&#xff0c;一种是对共享资源不进行任何同步原语保护&#xff1b;另一种是共享资源会出现被竞争的情况&#xff0c;但是不使用操作系统同步进行保护&a…

17、Spring6整合JUnit5

目录 17、Spring6整合JUnit5 17.1 Spring对JUnit4的支持 准备工作&#xff1a; 声明Bean spring.xml 单元测试&#xff1a; 17.2 Spring对JUnit5的支持 17、Spring6整合JUnit5 17.1 Spring对JUnit4的支持 准备工作&#xff1a; <?xml version"1.0" enco…

Java课题笔记~ MyBatis映射文件

映射文件是MyBatis中的重要组成部分&#xff0c;它包含了开发中编写的SQL语句、参数、结果集等。映射文件需要通过MyBatis配置文件中的<mapper>元素引入才能生效。MyBatis规定了映射文件的层次结构。 1、映射文件概览 <?xml version"1.0" encoding"…

浅谈document.write()输出样式

浅谈document.write()输出样式 js中的最基本的命令之一&#xff1a;document.write&#xff08;&#xff09;&#xff0c;用于简单的打印内容到页面上&#xff0c;可以逐字打印你需要的内容——document.write("content"),这里content就是需要输出的内容&#xff1b;…

2023 ChinaJoy 圆满闭幕,FairGuard游戏加固亮相 BTOB 展区

提振行业 产业复苏 2023年7月28日至7月31日&#xff0c;第二十届中国国际数码互动娱乐展览会( ChinaJoy)于上海新国际博览中心圆满举办。本届ChinaJoy作为疫情结束后的第一个国际性数字娱乐领域的重要产业盛会&#xff0c;对于提振行业信心、加快产业复苏、增进国际间的交流与…

如何成为linux服务端C++开发专家?

想成为linux服务端C开发专家&#xff0c;只能自己慢慢学&#xff0c;在实践中摸索&#xff0c;我敢说没几个人说自己是linux服务端C开发专家 ! 这里说下鹅厂关于Linux C方向 的使用场景 。 进腾讯最好的方向是 Linux C方向&#xff0c;目前腾讯由于历史原因&#xff0c;还有游…