[vitepress]前端团队终于有了自己的开发文档
前言
最近在使用 Element Plus 的时候,我一直在考虑,是否需要在自己的使用的组件库写一套开发文档,方便组内其他开发使用和分享,所以想到就开干。当然大家需要对什么是 VitePress? | VitePress中文网 (vitejs.cn)有所了解。如果想直接使用请拉到最后。
研究Element Plus的写法
我先去扒了 Element Plus 的源码,发现其文档中的写法是这样的
但实际上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