likes
comments
collection
share

[vitepress]前端团队终于有了自己的开发文档

作者站长头像
站长
· 阅读数 51

前言

最近在使用 Element Plus 的时候,我一直在考虑,是否需要在自己的使用的组件库写一套开发文档,方便组内其他开发使用和分享,所以想到就开干。当然大家需要对什么是 VitePress? | VitePress中文网 (vitejs.cn)有所了解。如果想直接使用请拉到最后。

研究Element Plus的写法

我先去扒了 Element Plus 的源码,发现其文档中的写法是这样的

[vitepress]前端团队终于有了自己的开发文档

[vitepress]前端团队终于有了自己的开发文档

但实际上markdown是没有 :::demo 这样的写法的。深入挖掘,发现 Element Plus 在编译的时候将所有以 :::demo 或者 :::tip 开头的都进行了转换。

export const mdPlugin = (md: MarkdownIt) => {
  // 这边的类似于vue的creatApp
  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 /* means the tag is opening */) {
        const description = m && m.length > 1 ? m[1] : '';
        const sourceFileToken = tokens[idx + 2];
        let source = '';
        const sourceFile = sourceFileToken.children?.[0].content ?? '';
        if (sourceFileToken.type === 'inline') {
          // 这边是查找对应的文件路径
          source = fs.readFileSync(
            path.resolve('docs', 'examples', `${sourceFile}.vue`),
            'utf-8'
          );
        }
        if (!source) throw new Error(`Incorrect source file: ${sourceFile}`);
        
        // 返回一个名为Demo的组件 其中source为code高亮,path为对应路径,description为描述。
        return `<Demo :demos="demos" source="${encodeURIComponent(
          highlight(source, 'vue')
        )}" path="${sourceFile}" raw-source="${encodeURIComponent(
          source
        )}" description="${encodeURIComponent(localMd.render(description))}">`
      } else {
        return '</Demo>';
      }
    },
  } as ContainerOpts);
};

然后追根溯源,我去寻找了这个名为Demo的组件,在 Element Plus 里面注册成为了全局组件。利用全局组件性质,将所有markdown内的 :::demo 转化为组件。但是在 Element Plus 中写法比较离谱,甚至他在 vitepress 中用到了 vue.config.ts ,也就是意味着在 vitepress 框架中还有一个 vite 框架。并通过这个 vite 框架,在每个页面中加入下面的核心代码。

<script setup>
 const demos = import.meta.globEager('../../examples/${componentId}/*.vue')
</script>

对于我们自己写的简易页面,我觉得没必要用如此复杂,就优化掉了 Element Plus 额外的 vite 框架。本人在demo组件中用 defineAsyncComponent 异步渲染对应path的组件,也是完美实现 Element Plus 的效果。

import type { Component } from 'vue';
export const getModule = (path: string): () => Promise<Component> => {
  const moduleObj: Record<string, () => Promise<Component>> = import.meta.glob('/examples/**/*.vue')
  const initializePath: string = `/examples/${path}.vue`
  if (moduleObj[initializePath]) {
    return moduleObj[initializePath];
  } else {
    throw Error('当前路由引入错误')
  }
};

Starter

第一步 配置路由

[路由点这里]。

export const sidebar: DefaultTheme.Config['sidebar'] = {
  // 这边 key 为 docs目录下的路径
  '/vue3/': [
    {
      text: 'Vue3',
      items: [
        // text 为导航显示的名称,link 为文档路径 一定要加.md后缀 不然会实现不了上下页跳转
        { text: 'resize', link: '/vue3/resize/index.md' },
      ],
    },
  ],
  '/pixi/': [
    {
      text: 'PIXI动画',
      items: [
        { text: '平铺精灵', link: '/pixi/tileSpirits/index.md' },
        { text: '蒙版动画', link: '/pixi/graphics/index.md' },
      ],
    },
  ],
};

第二步 根据路由配置文档

在 docs 路径下根据路由创建对应的 md 文件,[举个栗子]

## <% 这边是样式配置 可以直接用默认的 %>

layoutClass: m-nav-layout
outline: [2, 3, 4]

---

# 指令式 resize

## <% demo 的使用方法,自己脑部一下 %>
:::demo 利用 document.defaultView.getComputedStyle()特性监听元素 css 变化

vue3/resize/index

:::

第三步 写自己的 vue 代码

如果没有用到第二步的 demo,就当我没写。。。 在 docs/examples 文件夹下,根据 demo 中配的路径去生成那个 vue 文件,就完事了。

项目地址

vitePress: 基于vitepress默认样式的文档管理系统 (gitee.com) 大佬们,觉得还可以的话可以给个小心心,球球了。

转载自:https://juejin.cn/post/7243520456979398693
评论
请登录