9.20. 组件库文档平台

349 阅读1分钟

一、介绍

给你们项目的公共组件写文档,可以查看组件效果 查看代码结构; image.png

成熟框架:

使用loader解析md文件

  • markdown-it 将 .md 文件转换为普通的 html 格式
  • raw-loader 将 .md 文件转换为普通的 string 格式

二、 vuepress用法

vuepress已经给你初始化了模版,你按照它的规则配置即可:

  • 主题、路由、打包等配置 .vuepress/config.js
  • 路由,依赖组件等应用级别 .vuepress/enhanceApp.js

使用步骤

  • 配置 .vuepress/config.js npm i vuepress-plugin-demo-container
module.exports = {
  plugins: ['demo-container'],
  configureWebpack: {
    resolve:{
       alias:{
         "@":"../../src"
       }
    },
    module:{
      rules:[
        {
          "sass-loader",
          {
            loader:"sass-resources-loader",
            option:{
              resources:resolve(__dirname,'../../src/themes/src/index.scss')
            }
          }
        }
      ]
    }
  }
}
  • 引入组件库代码.vuepress/enhanceApp.js
import myUI from '@/component'
export default ({
  Vue, 
}) => {
 Vue.use(myUI)
}
  • 编写md
::: demo
code
:::

二、element组件库

element-vue

  • 自定义 md-loader 解析md,引入了 markdown-it 包;
  • 遇到 ::demo 标识替换为自定义组件来展示 code

build/md-loader/index.js

const mdContainer = require('markdown-it-container');

module.exports = md => {
  md.use(mdContainer, 'demo', {
    // 验证是否存在代码块标记
    validate(params) {
      return params.trim().match(/^demo\s*(.*)$/);
    },
    render(tokens, idx) {
      const m = tokens[idx].info.trim().match(/^demo\s*(.*)$/);
      if (tokens[idx].nesting === 1) {
        const description = m && m.length > 1 ? m[1] : '';
        const content = tokens[idx + 1].type === 'fence' ? tokens[idx + 1].content : '';
        return `<demo-block>
        ${description ? `<div>${md.render(description)}</div>` : ''}
        <!--element-demo: ${content}:element-demo-->
        `;
      }
      return '</demo-block>';
    }
  });

  md.use(mdContainer, 'tip');
  md.use(mdContainer, 'warning');
};

element-react

  • 自定义 loader 解析md,引入了 raw-loader 包将md解析为string;
  • 效果:ReactDOM.render()来渲染组件;
  • 代码:使用 codemirror;

libs/markdown/canvas.jsx

renderSource(value) {
    import('../../src').then(Element => {
      const args = ['context', 'React', 'ReactDOM']
      const argv = [this, React, ReactDOM]

      for (const key in Element) {
        args.push(key)
        argv.push(Element[key])
      }

      return {
        args,
        argv
      }
    }).then(({ args, argv }) => {
      const code = transform(`
        class Demo extends React.Component {
          ${value}
        }

        ReactDOM.render(<Demo {...context.props} />, document.getElementById('${this.playerId}'))
      `, {
        presets: ['es2015', 'react']
      }).code

      args.push(code)

      new Function(...args).apply(null, argv)

      this.source[2] = value
    }).catch((err) => {
      if (process.env.NODE_ENV !== 'production') {
        throw err;
      }
    })
  }

element-plus

  • 使用 vitepress框架
  • markdown: {config: (md) => mdPlugin(md)}定义md解析
  • 自定义文档主题 docs/.vitepress/theme/index.ts
import ElementPlus from 'element-plus'

import VPApp, { NotFound, globals } from '../vitepress'
import { define } from '../utils/types'
import 'uno.css'
import './style.css'
import type { Theme } from 'vitepress'

export default define<Theme>({
  NotFound,
  Layout: VPApp,
  enhanceApp: ({ app }) => {
    app.use(ElementPlus)

    globals.forEach(([name, Comp]) => {
      app.component(name, Comp)
    })
  },
})

欢迎关注我的前端自检清单,我和你一起成长