04 - Vue3 UI Framework - 文档页
官网的首页做完了,接下来开始做官网的文档页
返回阅读列表点击 这里
路由设计
先想想我们需要文档页通向哪些地方,这里直接给出我的设计:
| 所属 | 子标题 | 跳转路径 | 文件名(*.vue) |
|---|---|---|---|
| 指南 | 介绍 | /document/introduction | Introduction |
| 指南 | 安装 | /document/install | Install |
| 指南 | 快速上手 | /document/start | Start |
| 组件 | Button | /document/button | Button |
| 组件 | Dialog | /document/dialog | Dialog |
| 组件 | Switch | /document/switch | Switch |
| 组件 | Tabs | /document/tabs | Tabs |
大致就做如上的子内容
然后在 src/components 目录下新建需要的文件们,此处举例 Introduction.vue
<template>
<div>介绍</div>
</template>
<script lang="ts">
export default {
};
</script>
<style lang="scss" scoped>
</style>
再配置 router.ts 以路由
此处使用嵌套路由
// router.ts
import { createWebHistory, createRouter } from 'vue-router'
import Home from './views/Home.vue'
import Document from './views/Document.vue'
import Introduction from './components/Introduction.vue'
import Install from './components/Install.vue'
import Start from './components/Start.vue'
import Button from './components/Button.vue'
import Dialog from './components/Dialog.vue'
import Switch from './components/Switch.vue'
import Tabs from './components/Tabs.vue'
const history = createWebHistory()
const router = createRouter({
history,
routes: [
{ path: '/', component: Home },
{
path: '/document', component: Document, children: [
{ path: '', redirect: '/document/introduction' }, // 默认进入介绍页面
{ path: 'introduction', component: Introduction },
{ path: 'install', component: Install },
{ path: 'start', component: Start },
{ path: 'button', component: Button },
{ path: 'dialog', component: Dialog },
{ path: 'switch', component: Switch },
{ path: 'tabs', component: Tabs },
]
}
]
})
export default router
骨架
然后搭个骨架吧,已知文档页要显示
- 顶边栏
- 菜单
- 内容区域
容易得到如下骨架
<template>
<div class="layout">
<Topnav class="nav" />
<div class="content">
<aside>
<div class="aside-list">
<h2>指南</h2>
<ol>
<li>
<router-link to="/document/introduction">介绍</router-link>
</li>
<li>
<router-link to="/document/introduction">安装</router-link>
</li>
<li>
<router-link to="/document/introduction">快速上手</router-link>
</li>
</ol>
</div>
<div class="aside-list">
<h2>组件列表</h2>
<ol>
<li>
<router-link to="/document/button">Button</router-link>
</li>
<li>
<router-link to="/document/dialog">Dialog</router-link>
</li>
<li>
<router-link to="/document/switch">Switch</router-link>
</li>
<li>
<router-link to="/document/tabs">Tabs</router-link>
</li>
</ol>
</div>
</aside>
<main class="main-body">
<router-view :key="$route.fullPath" />
</main>
</div>
</div>
</template>
然后加上基本的布局样式表
.layout {
display: flex;
flex-direction: column;
height: 100vh;
> .nav {
flex-shrink: 0;
}
> .content {
flex-grow: 1;
padding-top: 90px;
padding-left: 210px;
@media (max-width: 500px) {
padding-left: 0;
}
}
}
.content {
display: flex;
}
侧边栏
重复代码不少,可以优化一下,先在 script 中声明数组:
setup() {
const componentsList = ["Button", "Dialog", "Switch", "Tabs"];
const guidancesList = [
{ path: "introduction", title: "介绍" },
{ path: "install", title: "安装" },
{ path: "start", title: "快速上手" },
];
return {
componentsList,
guidancesList,
};
}
然后在模板中引入
<aside>
<div class="aside-list">
<h2>指南</h2>
<ol>
<li v-for="(guidance, index) in guidancesList" :key="index">
<router-link :to="'/document/' + guidance.path">
{{ guidance.title }}
</router-link>
</li>
</ol>
</div>
<div class="aside-list">
<h2>组件列表</h2>
<ol>
<li v-for="(component, index) in componentsList" :key="index">
<router-link :to="'/document/' + component.toLowerCase()">
{{ component }}
</router-link>
</li>
</ol>
</div>
</aside>
最后补全样式表
<style lang="scss" scoped>
$base-color: #8c6fef;
$aside-index: 10;
$active-color: linear-gradient(
90deg,
rgba(255, 255, 255, 1) 0%,
rgba(255, 255, 255, 1) 97%,
$base-color 97%,
$base-color 100%
);
.layout {
display: flex;
flex-direction: column;
height: 100vh;
> .nav {
flex-shrink: 0;
}
> .content {
flex-grow: 1;
padding-top: 90px;
padding-left: 210px;
@media (max-width: 500px) {
padding-left: 0;
}
}
}
.content {
display: flex;
> aside {
flex-shrink: 0;
width: 200px;
padding: 16px 0;
position: absolute;
top: 0;
left: 0;
padding-top: 90px;
height: 100%;
z-index: $aside-index;
> .aside-list {
margin: 12px 0;
> h2 {
margin-bottom: 4px;
padding: 4px 16px;
}
> ol {
> li {
> a {
display: block;
padding: 8px 32px;
text-decoration: none;
transition: background-color 100ms;
&:hover {
color: $base-color;
background: $active-color;
}
}
.router-link-active {
color: $base-color;
background: $active-color;
}
}
}
}
@media (max-width: 500px) {
background: #8c6fef;
width: 100%;
height: auto;
}
}
> main {
overflow: auto;
flex-grow: 1;
padding: 16px;
background: white;
// border: 1px solid red;
margin-top: 4px;
margin-right: 10px;
@media (max-width: 500px) {
margin-left: 10px;
}
}
}
</style>
就可以做到移动的时候会浮光的侧边栏了。
内容区
先填充一下文档,然后用 border 法调整文本位置,得到如下调整
.content > main {
overflow: auto;
flex-grow: 1;
padding: 16px;
background: white;
margin-top: 4px;
margin-right: 10px;
@media (max-width: 500px) {
margin-left: 10px;
}
}
效果就不贴了,反正只是 padding 的调整
功能
在文档页,还应当可以控制顶边栏上的”弹出菜单”按键的是否可见,显然默认是允许在文档页显示的,所以在模板中调整 Topnav 为
<Topnav toggleMenuButtonVisible class="nav" />
然后获得对菜单的引用
const aside = ref<HTMLDivElement>(null);
<aside v-if="menuVisible" ref="aside"></aside>
再读取 App.vue 提供的 menuVisible,并实现隐藏菜单的方法
const menuVisible = inject<Ref<boolean>>("menuVisible");
const hideMenu = (event) => {
let target: Node = event.target;
if (!(target instanceof HTMLAnchorElement)) {
while (target.parentNode && target.parentNode !== document.body) {
target = target.parentNode;
if (target === aside.value) {
return;
}
}
}
if (document.documentElement.clientWidth <= 500) {
menuVisible.value = false;
}
};
所以有如下 script
import Topnav from "../components/Topnav.vue";
import { inject, ref, Ref } from "vue";
export default {
components: {
Topnav,
},
setup() {
const componentsList = ["Button", "Dialog", "Switch", "Tabs"];
const guidancesList = [
{ path: "introduction", title: "介绍" },
{ path: "install", title: "安装" },
{ path: "start", title: "快速上手" },
];
const aside = ref<HTMLDivElement>(null);
const menuVisible = inject<Ref<boolean>>("menuVisible");
const hideMenu = (event) => {
let target: Node = event.target;
if (!(target instanceof HTMLAnchorElement)) {
while (target.parentNode && target.parentNode !== document.body) {
target = target.parentNode;
if (target === aside.value) {
return;
}
}
}
if (document.documentElement.clientWidth <= 500) {
menuVisible.value = false;
}
};
return {
componentsList,
guidancesList,
aside,
menuVisible,
hideMenu,
};
},
};
取得关闭方法后,通过事件委托,将方法挂载到 div.content 上
<div class="content" @click="hideMenu">
即可实现点击空白处也可以关闭弹出菜单了。
运行效果

感谢阅读
04 - Vue3 UI Framework - 文档页的更多相关文章
- 00 - Vue3 UI Framework - 阅读辅助列表
阅读列表 01 - Vue3 UI Framework - 开始 02 - Vue3 UI Framework - 顶部边栏 03 - Vue3 UI Framework - 首页 04 - Vue3 ...
- 01 - Vue3 UI Framework - 开始
写在前面 一年多没写过博客了,工作.生活逐渐磨平了棱角. 写代码容易,写博客难,坚持写高水平的技术博客更难. 技术控决定慢慢拾起这份坚持,用作技术学习的阶段性总结. 返回阅读列表点击 这里 开始 大前 ...
- 03 - Vue3 UI Framework - 首页
顶部边栏做完了,接下来开始做官网的首页 返回阅读列表点击 这里 创建视图文件夹 让我们先新建一个 src/views 文件夹,用来存放官网的主要视图 然后在该文件夹下新建两个 vue 文件,作为我们的 ...
- 厨娘ui设计文档
厨娘ui设计文档 一.概述 中国的饮食文化从古到今源远流长.在生活日益丰富的今天,人们对饮食的要求不仅仅是温饱,更讲究健康和美味.近年来,饮食甚至成为娱乐的一部分,关于吃的流行用语层出不穷,可见在当今 ...
- Docz 用 MDX 写 React UI 组件文档
Docz 用 MDX 写 React UI 组件文档 前言 为了提升开发效率,创建一套 UI 组件库是一种较为有效的方式之一:可以减少重复工作.提高可复用,所以现在越来越多团队开始创建自己的 UI 组 ...
- 微软Bot Framework文档中,关于Sign-in Card的一处代码错误及更正
Bot Framework文档出错处网址:https://docs.botframework.com/en-us/csharp/builder/sdkreference/attachments.htm ...
- 去除word文档页眉处的横杠
如何去除上图word文档页眉处的横杠 wps软件使用者 第一步双击页眉,到页眉页脚: 第一步点击上图页眉横线,点击无线型或者删除横线即可: Microsoft Office 专业增 ...
- 02 - Vue3 UI Framework - 顶部边栏
顶部边栏比较简单,而且首页和文档页都需要,所以我们先从顶部边栏做起 前文回顾点击 这里 返回阅读列表点击 这里 初始化 首先,在 components 文件夹下,创建一个 vue 组件,命名为 Top ...
- Spring系列(零) Spring Framework 文档中文翻译
Spring 框架文档(核心篇1和2) Version 5.1.3.RELEASE 最新的, 更新的笔记, 支持的版本和其他主题,独立的发布版本等, 是在Github Wiki 项目维护的. 总览 历 ...
随机推荐
- Ubuntu安装BCC
Ubuntu安装BCC 教程 官方文档 安装 这里官方文档中首先讲到的是二进制文件的安装,直接通过apt进行安装 sudo apt-get install bpfcc-tools linux-head ...
- GitHub出现Permission denied (publickey)
Permission denied (publickey) 没有权限的publickey 重新生成一次ssh key即可解决 ssh-keygen -t rsa -C "这里输入你的邮箱&q ...
- 大爽Python入门教程 0-4 安装Pycharm
大爽Python入门公开课教案 点击查看教程总目录 安装重量级IDE--Pycharm 一 下载 下面步骤1,2中网络卡顿的朋友, 请直接前往步骤3来下载. 使用搜索引擎搜索Pycharm, 打开搜索 ...
- python实现模板匹配
目录: (一)原理 (二)代码实现和几种常见的模板匹配算法 正文: (一)原理 在待检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大. 作用有局限性, ...
- JS和JQUERY常见函数封装方式
JS中常用的封装函数4种方法: 1. 函数封装法: function box(){ } 2. 封装成对象 : let Cookie = { get(){ }, set(){ } } 3. 封装成构造函 ...
- 【Java】运行时Java对象在内存中是如何存储的?
翻译自这一篇文章 我们知道函数在内存中实现为一个活动记录的栈.我们也知道Java方法在JVM栈区中实现为一个帧栈而Java对象是在堆区进行分配的. Java对象在堆内存中是怎样的呢?一旦对象保存在内存 ...
- 带allow-create的el-select限制长度
需求:给el-select添加新增字段长度限制且新增内容不能为空 1.首先给el-select绑定一个id(例如:selectSku),这个id会传到组件里面,绑定在那个input上面, <el ...
- C#.NET 操作Windows服务承载WCF
Windows服务的制作.安装可以参考这篇: C#.NET 操作Windows服务(安装.卸载) - runliuv - 博客园 (cnblogs.com) 本篇会在这个解决方案基础上,继续修改. 一 ...
- 全面了解 Javascript Prototype Chain 原型链
原型链可以说是Javascript的核心特征之一,当然也是难点之一.学过其它面向对象的编程语言后再学习Javascript多少会感到有些迷惑.虽然Javascript也可以说是面向对象的语言,但是其实 ...
- Atcoder Regular Contest 092 D - Two Faced Edges(图论+bitset 优化)
Atcoder 题面传送门 & 洛谷题面传送门 orz ymx,ymx ddw %%% 首先既然题目要我们判断强连通分量个数是否改变,我们首先就将原图 SCC 缩个点呗,缩完点后我们很自然地将 ...