顶部边栏比较简单,而且首页和文档页都需要,所以我们先从顶部边栏做起

前文回顾点击 这里 返回阅读列表点击 这里

初始化

首先,在 components 文件夹下,创建一个 vue 组件,命名为 Topnav.vue ,然后快速创建 vue 模板,代码如下:

点击查看代码
<template>
<div> </div>
</template>
<script lang="ts">
export default { }
</script>
<style lang="scss" scoped> </style>

页面结构分析

分析顶部边栏的结构,可以得出如下表格信息:

功能 位置 默认状态 小于 500 px 时状态
首页跳转入口 左侧 可见 剧中
文档页跳转入口 右侧 可见 不可见
展开菜单按钮 左侧 不可见 可见

页面结构代码如下:

点击查看代码
<template>
<div class="topnav">
<router-link to="/">
首页
</router-link>
<router-link to="/document">
文档页
</router-link>
<button>
菜单
</button>
</div>
</template>

考虑到后续顶部菜单项扩展方便,这里最好做成一个列表

点击查看代码
<template>
<div class="topnav">
<router-link to="/" class="logo">
首页
</router-link>
<ul class="menu">
<li>
<router-link to="/document">
文档页
</router-link>
</li>
</ul>
<button @click="toggleMenu">
菜单
</button>
</div>
</template>

功能分析

需要的控制元素

顶边边栏中的弹出菜单按键,可以在引入它的组件中,被设置是否可见,那么应当有一个 Boolean 类型的变量来控制可见,且需要提供一个方法,控制菜单本体是否可见,但是,现在又犯难了——菜单本体是属于文档页的,而不是属于顶边栏的。如何跨组件控制呢 ?

回顾需求分析可得,通过弹出菜单按键,以及视口宽度,共同控制菜单是否可见,其中,视口宽度显然是一个全局属性,那么理应在 App.vue 中控制,于是我们在 App.vue 中定义其是否可见,并通过 provide/inject API 暴露给子组件,相关代码如下:

点击查看代码
<script lang="ts">
import { provide, ref } from "vue";
export default {
name: "App",
setup() {
const width = ref(document.documentElement.clientWidth);
const menuVisible = ref(width.value > 500 ? true : false);
window.onresize = () => {
width.value = document.documentElement.clientWidth;
if (width.value > 500) {
menuVisible.value = true;
} else {
menuVisible.value = false;
}
}; provide("menuVisible", menuVisible);
},
};
</script>

初始化时,可以根据视口宽度决定顶边栏的弹出菜单按键是否可见,并监听视口大小变化,根据视口宽度自动更新控制变量。

编写顶部边栏核心代码

Topnav.vue 代码如下:

点击查看代码
<script lang="ts">
import { inject, Ref } from "vue";
export default {
props: {
toggleMenuButtonVisible: {
type: Boolean,
default: false,
},
},
setup() {
const menuVisible = inject<Ref<boolean>>("menuVisible");
const toggleMenu = () => {
menuVisible.value = !menuVisible.value;
};
return {
toggleMenu,
};
},
};
</script>

注意一下

此处的 inject 需要注明变量的类型。因为 menuVisible 声明的时候是 ref(true|false),所以其类型为 Ref<boolean>

层叠样式表

尽量优化用户体验,我们这里做个简单的样式美化,底部采用渐变线的分割效果:

点击查看代码
<style lang="scss" scoped>
$color: #8c6fef;
.topnav {
color: $color;
display: flex;
background: linear-gradient(
180deg,
rgba(255, 255, 255, 1) 0%,
rgba(255, 255, 255, 1) 97%,
#8c6fef 97%,
#8c6fef 100%
);
padding: 0 32px;
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 20;
justify-content: center;
align-items: center;
> .logo {
max-width: 6em;
margin-right: auto;
> svg {
width: 80px;
height: 80px;
}
> img {
height: 80px;
}
}
> .menu {
display: flex;
white-space: nowrap;
flex-wrap: nowrap;
> li {
margin: 0 1em;
> a {
> svg {
width: 32px;
height: 32px;
}
> img {
height: 80px;
}
}
}
}
> .toggleAside {
width: 32px;
height: 32px;
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
display: none;
cursor: pointer;
}
@media (max-width: 500px) {
> .menu {
display: none;
}
> .logo {
margin: 0 auto;
}
> .toggleAside {
display: inline-block;
}
}
}
img {
padding: 6px 0;
}
</style>

至此,我们的顶部边栏组件已经完成了,接下来,我们把这个组件引入到 App.vue 中看下实际运行效果吧!

点击查看代码
<template>
<div class="app">
<router-view />
</div>
</template> <script lang="ts">
import { provide, ref } from "vue";
export default {
name: "App",
setup() {
const width = ref(document.documentElement.clientWidth);
const menuVisible = ref(width.value > 500 ? true : false);
window.onresize = () => {
width.value = document.documentElement.clientWidth;
if (width.value > 500) {
menuVisible.value = true;
} else {
menuVisible.value = false;
}
}; provide("menuVisible", menuVisible);
},
};
</script>
<style lang="scss" scoped>
$max-width: 1200px;
.app {
max-width: $max-width;
margin-left: calc(50vw - 600px);
position: relative;
@media (max-width: $max-width) {
margin-left: 0;
}
}
</style>

效果图

感谢阅读

02 - Vue3 UI Framework - 顶部边栏的更多相关文章

  1. 00 - Vue3 UI Framework - 阅读辅助列表

    阅读列表 01 - Vue3 UI Framework - 开始 02 - Vue3 UI Framework - 顶部边栏 03 - Vue3 UI Framework - 首页 04 - Vue3 ...

  2. 01 - Vue3 UI Framework - 开始

    写在前面 一年多没写过博客了,工作.生活逐渐磨平了棱角. 写代码容易,写博客难,坚持写高水平的技术博客更难. 技术控决定慢慢拾起这份坚持,用作技术学习的阶段性总结. 返回阅读列表点击 这里 开始 大前 ...

  3. 03 - Vue3 UI Framework - 首页

    顶部边栏做完了,接下来开始做官网的首页 返回阅读列表点击 这里 创建视图文件夹 让我们先新建一个 src/views 文件夹,用来存放官网的主要视图 然后在该文件夹下新建两个 vue 文件,作为我们的 ...

  4. 05 - Vue3 UI Framework - Button 组件

    官网基本做好了,接下来开始做核心组件 返回阅读列表点击 这里 目录准备 在项目 src 目录下创建 lib 文件夹,用来存放所有的核心组件吧.然后再在 lib 文件夹下创建 Button.vue 文件 ...

  5. 04 - Vue3 UI Framework - 文档页

    官网的首页做完了,接下来开始做官网的文档页 返回阅读列表点击 这里 路由设计 先想想我们需要文档页通向哪些地方,这里直接给出我的设计: 所属 子标题 跳转路径 文件名(*.vue) 指南 介绍 /do ...

  6. 06 - Vue3 UI Framework - Dialog 组件

    做完按钮之后,我们应该了解了遮罩层的概念,接下来我们来做 Dialog 组件! 返回阅读列表点击 这里 需求分析 默认是不可见的,在用户触发某个动作后变为可见 自带白板卡片,分为上中下三个区域,分别放 ...

  7. 08 - Vue3 UI Framework - Input 组件

    接下来再做一个常用的组件 - input 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 input 组件有两种类型,即 input 和 textarea 类型 当类型为 ...

  8. 09 - Vue3 UI Framework - Table 组件

    接下来做个自定义的表格组件,即 table 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 基于原生 table 标签的强语义 允许用户自定义表头.表体 可选是否具有边框 ...

  9. 10 - Vue3 UI Framework - Tabs 组件

    标签页是非常常用的组件,接下来我们来制作一个简单的 Tabs 组件 返回阅读列表点击 这里 需求分析 我们先做一个简单的需求分析 可以选择标签页排列的方向 选中的标签页应当有下划线高亮显示 切换选中时 ...

随机推荐

  1. Scrapy入门到放弃06:Spider中间件

    前言 写一写Spider中间件吧,都凌晨了,一点都不想写,主要是也没啥用...哦不,是平时用得少.因为工作上的事情,已经拖更好久了,这次就趁着半夜写一篇. Scrapy-deltafetch插件是在S ...

  2. <C#任务导引教程>练习四

    //27,创建一个控制台应用程序,声明两个DateTime类型的变量dt,获取系统的当前日期时间,然后使用Format格式化进行规范using System;class Program{    sta ...

  3. [loj2977]巧克力

    先考虑第一个问题,即求最小的巧克力块数 将这张网格图建图(仅对$c_{i,j}\ne -1$的位置建点),即求点数最少的连通块(的点数)使得存在$k$个不同的$c_{i,j}$ (以下$c$仅用一维数 ...

  4. [loj3339]美食家

    令$f[i][j]$表示第$i$个时刻走到点$j$的最小时间,暴力的$dp$复杂度为$o(tm)$ 如果没有限制,由于$w\le 5$,记录前5个时刻的状态即可求出当前状态,用矩阵乘法可优化到$o(n ...

  5. 31、下一个排列 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(31)下一个排列 一 题目描述 二 解法总览(思维导图) 三 全部解法 1 方案1 1)代码: // 方案1 "双指针法 ...

  6. CentOS7部署ceph

    CEPH 简介 不管你是想为云平台提供Ceph 对象存储和/或 Ceph 块设备,还是想部署一个 Ceph 文件系统或者把 Ceph 作为他用,所有 Ceph 存储集群的部署都始于部署一个个 Ceph ...

  7. 洛谷 P4094 [HEOI2016/TJOI2016]字符串(SA+主席树)

    题面传送门 一道码农题---- u1s1 感觉这类题目都挺套路的,就挑个有代表性的题写一篇题解罢. 首先注意到答案满足可二分性,故考虑二分答案 \(mid\),转化为判定性问题. 考虑怎样检验 \(m ...

  8. 使用BRAKER2进行基因组注释

    来自:https://www.jianshu.com/p/e6a5e1f85dda 使用BRAKER2进行基因组注释 BRAKER2是一个基因组注释流程,能够组合GeneMark,AUGUSTUS和转 ...

  9. zabbix忘记密码——进入数据库修改

    登录数据库,选择zabbix数据库 查看数据库里面的表 用户和用户密码在users表里面 将你想设置的密码进行MD5加密处理: 更新密码即可: update users set passwd=&quo ...

  10. fping (比ping更强大的ping工具)

    Fping程序类似于ping(ping是通过ICMP(网络控制信息协议InternetControl Message Protocol)协议回复请求以检测主机是否存在).Fping与ping不同的地方 ...