官网装修 - 文档页
[toc]
创建更多路由
分别创建介绍、安装和开始使用导航对应的组件
router.ts
- 路由路径一般小写,横杠链接
组件一般大写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32import ButtonDemo from '@/components/ButtonDemo.vue'; import DialogDemo from '@/components/DialogDemo.vue'; import DocsDemo from '@/components/DocsDemo.vue'; import SwitchDemo from '@/components/SwitchDemo.vue'; import TabsDemo from '@/components/TabsDemo.vue'; import Docs from '@/views/Docs.vue'; import GetStarted from '@/views/GetStarted.vue'; import Home from '@/views/Home.vue'; import Install from '@/views/Install.vue'; import Intro from '@/views/Intro.vue'; import {createRouter, createWebHashHistory} from 'vue-router'; const history = createWebHashHistory(); export const router = createRouter({ history, routes: [ {path: '/', component: Home}, { path: '/docs', component: Docs, children: [ {path: '', component: DocsDemo}, {path: 'intro', component: Intro}, {path: 'get-started', component: GetStarted}, {path: 'install', component: Install}, {path: 'switch', component: SwitchDemo}, {path: 'button', component: ButtonDemo}, {path: 'dialog', component: DialogDemo}, {path: 'tabs', component: TabsDemo}, ] }, ] });
高亮当前路由 router active class
- 高亮当前路由(模糊匹配)
- 使用
vue-router选中任意路由时自动添加的router-link-active类可以精确匹配router-link-active标记当前选中的类router-link-exact-active链接精准激活时,匹配选中项的类
选择给
router-link-exact-active类添加样式1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193<template> <div class="layout"> <top-nav class="nav" menuBtnVisible></top-nav> <div class="content"> <transition name="aside"> <aside v-if="asideVisible"> <header> <h2> <router-link class="alink" to="/docs">文档</router-link> </h2> </header> <ol> <li> <h3> <router-link class="router-link" to="/docs/intro">介绍</router-link> </h3> </li> <li> <h3> <router-link class="router-link" to="/docs/install">安装</router-link> </h3> </li> <li> <h3> <router-link class="router-link" to="/docs/get-started">开始使用</router-link> </h3> </li> </ol> <header> <h2> 组件列表 </h2> </header> <ol> <li> <h3> <router-link to="/docs/switch" class="router-link"> Switch 组件 </router-link> </h3> </li> <li> <h3> <router-link to="/docs/button" class="router-link"> Button 组件 </router-link> </h3> </li> <li> <h3> <router-link to="/docs/dialog" class="router-link"> Dialog 组件 </router-link> </h3> </li> <li> <h3> <router-link to="/docs/tabs" class="router-link"> Tabs 组件 </router-link> </h3> </li> </ol> </aside> </transition> <main> <router-view></router-view> </main> </div> </div> </template> <script setup lang="ts"> import {inject, Ref} from 'vue'; let asideVisible = inject<Ref<boolean>>('asideVisible'); </script> <script lang="ts"> import TopNav from '@/components/TopNav.vue'; export default { name: 'Docs', components: {TopNav} }; </script> <style lang="scss" scoped> .layout { display: flex; flex-direction: column; height: 100vh; > .nav { flex-shrink: 0; height: 5vh; } > .content { height: 95vh; display: flex; flex-grow: 1; padding-top: 60px; padding-left: 156px; @media screen and(max-width: 768px) { padding-left: 0; } > aside { flex-shrink: 0; position: fixed; top: 0; left: 0; background: linear-gradient( 145deg, rgba(183, 233, 230, 50) 100%, rgba(227, 255, 253, 1) 0%); width: 150px; padding: 60px 0 16px; height: 100vh; color: black; z-index: 1; > header { > h2 { margin-bottom: 4px; line-height: 50px; padding: 0 16px; user-select: none; } } > ol { display: flex; flex-direction: column; > li { > h3 { display: block; line-height: 25px; transition: .25s; padding-left: -16px; &:hover { transform: translate3D(4px, 0, 0); } .router-link { display: block; height: 100%; width: 100%; padding: 4px 16px; } .router-link-active { background-color: white; padding-left: -4px; } } } } } > main { flex-grow: 1; padding: 16px; background: white; overflow: auto; } .aside-enter-active, .aside-leave-active { transition: all 0.25s ease; } .aside-enter-from, .aside-leave-to { opacity: 0; transform: translate3D(-100%, 0, 0); } } } </style>
引入 Github 的 Markdown 样式
填充文档内容
Intro.vue
|
|
Install.vue
|
|
GetStarted.vue
|
|
使用
github-markdown-css为代码添加样式
- 安装
yarn add github-markdown-css - 在
main.ts中引入import 'github-markdown-css';- 黑暗模式
github-markdown-css/github-markdown-dark.css - 明亮模式
github-markdown-css/github-markdown-light.css
- 黑暗模式
- 在容器的标签上添加类
class="markdown-body"
这样写比较麻烦,考虑直接使用
*.md文件,转化为HTML标签,插入js文件中
添加支持 import markdown 文件
直接引入 Markdown 文件需要 ** Vite 插件 **
- 可以 自制 Vite 插件
- 或者使用
vite-plugin-md
自制Vite 插件
- Vite在开发项目时没有使用任何打包工具,使用浏览器自带的能力
- 浏览器不支持引入
*.md文件,但支持引入*.js文件 - 将
*.md文件转译为*.js文件,然后引入浏览器
新建目录与文件
plugins/md.ts
|
|
- 由于
md.ts引用了marked,需要安装yarn add --dev marked
在
vite.config.ts中调用md.ts
|
|
正式版vite已经不支持此种写法了,所以可以使用官方推荐的插件
vite-plugin-md
使用vite-plugin-md
解释一下 md.ts
- 用于开发 KOA
- 添加加载
*.md文件为*.js文件的功能 - 导出一个字符串
export default "<h1>..."
- 添加加载
- 用于 rollup 插件
- 对 .md文件进行编译
- 使用
mdToJs()方法将*.md转译为js代码
事不过三,消除重复
Don’t Repeat Yourself
|
|
三个组件的结构一致,可以用一个组件来代替
- 新建组件
src/view/Markdown.vue - 将导入语句的路径作为参数,参数数据由外界传入
props: {path: {type: String, required: true}}
- 在
setup() {}中动态异步地引入import(props.path),异步请求文件- 使用 顶层 await
- await 的表达式会自动编译成在 await 之后保留当前组件实例上下文的格式。
``
|
|
你的代码有什么缺点
- 不支持SSR
展示源代码
优化demo展示
SwitchDemo.vue
|
|
- demo分为四个部分
- 标题
h2 - 展示的组件
<VueSwitch /> - 切换按钮
<VueButton /> - 组件的源码
<div class="demo-code"><pre>...
- 标题
展示抽离的源代码,方便拷贝
|
|
使用vue-loader的Custom Blocks功能处理自定义标签
以
switch1demo.vue为例
|
|
写一个vite2.0插件
vueCompAddSourceCodeTitleFromCustomBlock.ts
- 处理自定义标签
<demo></demo> - vite 1.x 迁移 自定义块转换
transform(code, id)中的id其实所解析到的文件的 url- 使用正则匹配
/vue&type=demo/.test(id) - 去除多余的查询参数得到该文件路径
const path = id.replace(`?vue&type=demo&index=0&lang.demo`,'');
- 按路径读取文件内容
const fileString = fs.readFileSync(path).toString(); - 找出
<demo></demo>标签节点,并且得到文本const parsed = baseParse(fileString).children.find(n => n.tag === 'demo');const title = parsed.children[0].content;
- 得到代码主体
const main = fileString.split(parsed.loc.source).join('').trim(); - 给组件附加属性
Component.__sourceCode = ${JSON.stringify(main)}Component.__sourceCodeTitle = ${JSON.stringify(title)}
在模板字符串中返回 方法
js
import {baseParse} from ‘@vue/compiler-core’; import fs from ‘fs’;
// 自定义块转换 // 可以告诉 vite 在遇到 vue 文件的时候如何处理自定义块
// 获取组件源码 Component.sourceCode // 获取组件标题 Component.sourceCodeTitle export function vueCompAddSourceCodeTitleFromCustomBlock(customBlockName: string) { const regexp = new RegExp( vue&type=${customBlockName}); return { name: ‘vueCustomBlockTransforms’, transform: (code: string, id: string) => { if (!regexp.test(id)) { return; } const path = id .replace(?vue&type=${customBlockName}&index=0&lang.${customBlockName}, “); const fileString = fs.readFileSync(path).toString(); // @ts-ignore const parsed = baseParse(fileString).children.find(n => n.tag === ‘demo’); // demo 标题 // @ts-ignore const title = parsed.children[0].content; // 代码主体 // @ts-ignore const main = fileString.split(parsed.loc.source).join(“).trim();return
export default function (Component) { Component.__sourceCode = ${JSON.stringify(main)} Component.__sourceCodeTitle = ${JSON.stringify(title)} }.trim(); }, }; }```
配置
vite.config.ts
|
|
参考
小优化:使用 <component :is=""/>
五彩斑斓的源代码
使用
pismjs为显示的源代码加样式
- 安装
yarn add pismjs - 安装
yarn add @types/prismjs -D - 在需要显示源代码的组件中引入
import * as Prism from 'prismjs';,使用全局下的window.Prism- 不能使用
import 'pismjs' - 不能使用
import default from 'pismjs' - 样式
import 'prismjs/themes/prism-okaidia.css';
- 在
env.d.ts中声明模块类型declare module 'prismjs'; pismjs将每行代码字符串外都包裹一层span,加上相应的样式- 加背景色
<pre class="language-html" v-html="Prism.highlight(Switch1demo.__sourceCode, Prism.languages.html, 'html')"></pre>
神奇的封装:Demo 组件
事不过三 封装
<Demo component="x"/>组件 简化代码
|
|
使用mitt
main.ts
|
|
App.vue
|
|