创建更多路由
在views里面创建Intro(介绍),GetStarted(开始使用),Install(安装)组件
在router.ts里面创建路径,引入上面的组件
在Doc.vue里面添加路由链接<router-link to="。。。"><router-link>
高亮当前路由
设置选中路由的
在CSS中添加下面的代码
.router-link-active {
text-decoration: underline; //选中的路由下方有下划线
}
如果想要选中的整个区域变化,那router-link-active就没办法实现,会出现下图的效果
为什么会这样?因为这里是a标签,我们实际选中的区域是<li>,代码结构实际上是<li>
做法:不可能通过a标签控制<li>的样式,那么就让a标签充满<li>
> ol {
> li {
> a {
display: block;
padding: 4px 16px;
text-decoration: none;
}
.router-link-active {
background: white;
}
}
}
引入GitHub的Markdown样式
将文档的内容写好
运行yarn add github-markdown-css
这时,会出现报错,但是加上对应的版本号就可以了
yarn add github-markdown-css@4.0.0
运行成功。在每个<article>标签内加上markdown-body,即
<article class="markdown-body">
。。。
</article>
支持 import markdown 文件
自制vite插件
搜索 Vue3 vite plugin
创建一个plugin/md.ts的插件
md.ts
// @ts-nocheck
import path from "path";
import fs from "fs";
import marked from "marked";
const mdToJs = (str) => {
const content = JSON.stringify(marked(str));
return `export default ${content}`;
};
export function md() {
return {
configureServer: [
// 用于开发
async ({ app }) => {
app.use(async (ctx, next) => {
// koa 是个web框架
if (ctx.path.endsWith(".md")) {
ctx.type = "js";
const filePath = path.join(process.cwd(), ctx.path);
ctx.body = mdToJs(fs.readFileSync(filePath).toString());
} else {
await next();
}
});
},
],
transforms: [
{
// 用于 rollup // 插件
test: (context) => context.path.endsWith(".md"),
transform: ({ code }) => mdToJs(code),
},
],
};
}
由于md.ts引用了marked,所以要安装marked
命令如下:
yarn add --dev marked
或者
npm i -D marked
再创建vite.config.ts文件
vite.config.ts
// @ts-nocheck
import { md } from "./plugins/md";
export default {
plugins: [md()],
};
然后就可以创建markdown/intro.md,markdown/get-started.md,markdown/install.md,将内容转到.md文件内,即可用marked的语法
vite在开发的时候用的是浏览器的原生能力,部署的时候用的是rollup,md.ts是否支持rollup?(答案是支持的)
运行yarn build,得到三个文件(js文件,css文件,html文件)
再运行yarn global add http-server
安装后使用http-server dist/ -c-1
消灭重复
将重复的代码消灭,创建Markdown.vue组件,将重复的代码给提取到Markdown.vue
接受一个参数,props在初始化的时候执行,import ... from ......是在引入的时候执行
import md from props.path只能写在文件外面,不能写在setup里面,如果写在文件里面是会自动的移到文件外面去,可以用动态import(props.path)
动态import
import(props.path)
动态import 同之前的 import ... from .... 的区别是:动态import 是异步去加载
在开发者工具里面,可以看到Markdown.vue有去请求Intro.vue里面的文件
然后不写动态import的话,就不会有该请求
那我们知道了动态import是异步的请求,异步返回内容(可以用await,但是会出现bug,因为setup是不支持async的,如果外面没有写async,里面是不能用await的),我们可以声明一个容器(content)来容纳一个值
setup(props) {
const content = ref<string>(null); //声明一个容器
import(props.path).then((result) => {
content.value = result.default;
});
//等加载成功之后,在成功回调里面得到result
},
为什么写default?
因为result里面有一个default属性
结论:动态import得到的东西,有一个默认的default属性,通过default才能得到它的默认导出
content的值从原来的null,文件加载成功之后,就变成了md
- 如何证明是异步的?
使用
setTimeout(() => {
content.value = result.default
}, 10000)
在main.ts里面添加组件Markdown
在router.ts添加路由路径,引入Markdown.vue
展示源代码
方便用户拷贝
需要使用vue-loader的custom的blocks功能
创建Switch1Demo.vue和Switch2Demo.vue
<demo>
常规用法
</demo>
<template>
<Switch v-model:value="bool" />
</template>
<script>
import { ref } from "vue";
import Switch from "../lib/Switch.vue";
export default {
components: { Switch },
setup() {
const bool = ref(false);
return { bool };
},
};
</script>
如何将代码显示到页面:使用<demo></demo>,将SwitchDemo.vue的内容插入到页面;在SwitchDemo.vue里面的想要显示的代码内容用<pre>{{ Switch1Demo.__sourceCode }}</pre>包裹
插件<Switch1Demo/>等价于 <component :is="Switch1Demo" />。
<template>
<div>
<h1>Switch 组件示例</h1>
<div class="demo">
<h2>常规用法</h2>
<div class="demo-component">
<component :is="Switch1Demo" />
</div>
<div class="demo-actions">
<Button>查看代码</Button>
</div>
<div class="demo-code">
<pre>{{ Switch1Demo.__sourceCode }}</pre>
</div>
</div>
<div class="demo">
<h2>支持 disabled</h2>
<div class="demo-component">
<component :is="Switch2Demo" />
</div>
<div class="demo-actions">
<Button>查看代码</Button>
</div>
<div class="demo-code">
<pre>{{ Switch2Demo.__sourceCode }}</pre>
</div>
</div>
</div>
</template>
<script lang="ts">
import { ref } from "vue";
import Switch from "../lib/Switch.vue";
import Button from "../lib/Button.vue";
import Switch1Demo from "./Switch1.demo.vue";
import Switch2Demo from "./Switch2.demo.vue";
export default {
components: { Button },
setup() {
const bool = ref(false);
return { bool, Switch1Demo, Switch2Demo };
},
};
</script>
如何高亮源代码
使用prismjs和v-html
运行
yarn add prismjs
引入prismjs和prismjs/themes/prism-okaidia.css
import "prismjs";
import "prismjs/themes/prism-okaidia.css";
const Prism = (window as any).Prism;
<div class="demo-code">
<pre
class="language-html"
v-html="Prism.highlight(Switch2Demo.__sourceCode, Prism.languages.html, 'html')" />
</div>
Demo组件
<Demo component="x" />
新建一个Demo.vue的文件
想在任何一个地方展示Demo,只需要引入这个组件,然后return这个组件,然后组件放到<Demo :component="组件名" />
Demo.vue
<template>
<div class="demo">
<h2>{{ component.__sourceCodeTitle }}</h2>
<div class="demo-component">
<component :is="component" />
</div>
<div class="demo-actions">
<Button @click="toggleCode">查看代码</Button>
</div>
<div class="demo-code" v-if="codeVisible">
<pre class="language-html" v-html="html" />
</div>
</div>
</template>
<script lang="ts">
import "prismjs";
import "prismjs/themes/prism-okaidia.css";
import Button from "../lib/Button.vue";
import { computed, ref } from "vue";
const Prism = (window as any).Prism;
export default {
components: {
Button,
},
props: {
component: Object,
},
setup(props) {
const html = computed(() => {
return Prism.highlight(
props.component.__sourceCode,
Prism.languages.html,
"html"
);
}); //html是component计算出来的属性
const toggleCode = () => (codeVisible.value = !codeVisible.value);
const codeVisible = ref(false);
return { Prism, html, codeVisible, toggleCode };
},
};
</script>
然后在需要引入的文件里面使用<Demo :component="组件名">
完善代码
点击开始的后跳转到介绍里面
将跳转路径改为redirect: "/doc/intro"