全栈项目开发——NOTEBOOK(7):noteClass菜单栏的开发
前言
在上一篇的文章中我们使用请求拦截器实现了JWT token 在前后端的流通,大大提高了app的安全机制,对我们需要登入才能访问页面起到了一个很好的保护。今天我们的任务就是开发首页 noteClass
一,设计首页
Vant开发
我们想要设计的是一本生活笔记,在不同的栏框可以记录不同的事情。我们可以借助Vant进行首页开发。在Vant中选择我们想要的组件,点击后将自动复制,我们将他们引入首页中。
1. 引入Icon
我们首先需要在main.js引入组件icon,和我们第一章开发登入页面时候一样。
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import 'lib-flexible/flexible.js'
// 1. 引入你需要的组件
import { Button, Form, Field, CellGroup, Icon } from 'vant';
// 2. 引入组件样式
import 'vant/lib/index.css';
import router from './router/index.js'
const app = createApp(App)
app.use(Button);
app.use(Form);
app.use(Field);
app.use(CellGroup);
app.use(Icon);
app.use(createPinia())
app.use(router)
// 3. 注册你需要的组件
app.mount('#app')
2. 引入图标
在Vant库中选择你需要的组件,在你需要的组件中寻找图标
需要用到的四个图标我已经为大家准备好了
<header>
<div>
<van-icon name="wap-nav" @click="isShowMenu = !isShowMenu" />
</div>
<div>
<van-icon name="edit" />
<van-icon name="like-o" />
<van-icon name="search" />
</div>
</header>
四个图标:

二,开发页面
页面需要展示的内容如下,我们可以将他们放入section标签中,然后循环遍历他们的名字,颜色,生成一框框栏目。
const noteClassList = [
{ bgColor: "#f0aa84", title: "美食" },
{ bgColor: "#dcf189", title: "旅行" },
{ bgColor: "#e0c2f1", title: "恋爱" },
{ bgColor: "#c2ebf1", title: "学习" },
{ bgColor: "#949c9d", title: "吵架" },
];
1. 设计页面结构
- 将四个导航栏图标放入 < header>
- 将上述内容响应式放入< section> ,
- 使用 v-for="(item, index) in noteClassList" 循环遍历配合{{ item.title }}实现title 的遍历添加
- :style="{ backgroundColor: item.bgColor } 配置好每一个item.title 对应的颜色
- @click="goNoteList(item.title) 绑定点击事件,在js中实现当点击事件触发时会跳转到对应页面
<template>
<div class="note-class-wrapper">
<div class="note-class" :class="{ 'hide': isShowMenu }">
<header>
<div>
<van-icon name="wap-nav" @click="isShowMenu = !isShowMenu" />
</div>
<div>
<van-icon name="edit" />
<van-icon name="like-o" />
<van-icon name="search" />
</div>
</header>
<section>
<div class="note-item" v-for="(item, index) in noteClassList" :key="index"
:style="{ backgroundColor: item.bgColor }" @click="goNoteList(item.title)">
<span class="title">{{ item.title }}</span>
</div>
</section>
</div>
<Menu class="menu" :class="{ 'show': isShowMenu }" @hidden="handle" />
</div>
</template>
2. 页面样式
设计页面样式,内容较为基础,主要提几点
- box-sizing: border-box;
- overflow-y: scroll;
- overflow: hidden;
- justify-content: space-between;
- align-items: center;
<style lang="less" scoped>
.note-class-wrapper {
width: 100vw;
height: 100vh;
overflow: hidden;
position: relative;
.note-class {
position: absolute;
width: 100%;
height: 100%;
padding: 0.5866rem;
box-sizing: border-box;
overflow-y: scroll;
transition: all 0.5s;
&.hide {
transform: translateX(100%);
}
header {
display: flex;
justify-content: space-between;
align-items: center;
height: 1.2rem;
font-size: 1rem;
van-icon {
font-size: 1.2rem;
margin: 0, 0.2rem;
}
}
section {
width: 100%;
.note-item {
height: 3.2rem;
border-radius: 0.3rem;
margin: 0.6rem 0;
background-color: #f1f1f1;
box-shadow: 0 4px 10px 5px #c0c0c0;
overflow: hidden;
.title {
display: block;
font-size: 0.5rem;
color: #ff6f00;
margin-top: 0.3rem;
text-align: center;
}
}
}
}
.menu {
width: 100%;
height: 100%;
position: absolute;
transform: translateX(-100%);
transition: all 0.5s;
&.show {
transform: translateX(0);
}
}
}
</style>
三, 开发菜单栏
1. 点击菜单栏,菜单页面滑出
相信大家都看到了上文中部分别有用心的代码
template中:
</div>
<Menu class="menu" :class="{ 'show': isShowMenu }" @hidden="handle" />
</div>
style中:
transition: all 0.5s;
&.hide {
transform: translateX(100%);
}
.menu {
width: 100%;
height: 100%;
position: absolute;
transform: translateX(-100%);
transition: all 0.5s;
&.show {
transform: translateX(0);
}
}
- 设置了class="menu",并为其设置了动画transition
- 利用 transform: translateX() 的位置变化配合transition实现动画效果
- 绑定点击事件@hidden="handle 控制菜单的出现消失
显然,我想实现的功能是当点击菜单按钮时菜单页面从左侧滑进来,再次点击滑出。所有我们接下来开发菜单页面
2. 设计菜单页面
- 页面框架:
- template部分:
<template>
<div class="menu-wrap">
<div class="back" @click="hideMenu">
<van-icon name="arrow-left" size="26px" />
</div>
<section class="header">
<div class="avatar">
<img src="@/assets/2.jpg" alt="头像">
</div>
<p class="user">绵绵冰</p>
</section>
<div class="setting">
<div class="set-item">
<van-icon name="contact" size="0.4rem" />
<span>个人主页</span>
</div>
<div class="set-item">
<van-icon name="bullhorn-o" size="0.4rem" />
<span>通知</span>
</div>
<div class="set-item">
<van-icon name="revoke" size="0.4rem" />
<span>退出登录</span>
</div>
</div>
</div>
</template>
- style部分:
<style lang="less" scoped>
.menu-wrap {
background-color: #e8e6e8;
padding: 1.4rem 1rem;
box-sizing: border-box;
.back {
position: absolute;
top: 15px;
left: 15px;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
.avatar {
width: 2rem;
height: 2rem;
border-radius: 50%;
overflow: hidden;
margin-bottom: 10px;
img {
width: 100%;
}
}
.user {
color: #101010;
font-size: 0.37333rem;
}
}
.setting {
margin-top: 1rem;
padding-left: 30%;
.set-item {
height: 1.2rem;
line-height: 1.2rem;
span {
font-size: 0.4rem;
color: #101010;
margin-left: 10px;
}
}
}
}
</style>
3. 实现页面滑动切换效果
分析一波,
我们为 note-class 添加类名为hide
.note-class { // xxx //
transform: translateX(0%);
transition: all 0.5s;
&.hide {
transform: translateX(100%);
}
为 menu 添加的类名为show
.menu { // xxx //
transform: translateX(-100%);
transition: all 0.5s;
&.show {
transform: translateX(0%);
}
}
}
两者页面同级相互遮挡,只会显示一个页面
使用 v-bind 绑定类名,再利用布尔值可以实现动态的添加类名
<div class="note-class" :class="{ 'hide': isShowMenu }"></div>
当 isShowMenu 为false 时,menu在视窗外的左侧,这时主页面是 note-class,即父组件,当再次点击菜单栏时我们将isShowMenu的值变为true,这时 类名hide,show 都将生效,menu将移回主页位置,note-class将会移到视窗右侧。根据isShowMenu布尔值的改变两个页面将来回移动。
我们通过子向父通讯,控制 isShowMenu 的值
在Menu.vue中创建一个事件——hidden , 通过 emits('hidden') 将事件发布,携带参数,在note-class中通过 @hidden="handle" 绑定,只有当hidden被发布时handle才触发,并将isShowMenu.value改为false;
-
给菜单页的箭头back绑定点击事件hideMenu,触发时将向父组件发布事件
-
给note-class中的菜单栏wap-nav绑定点击事件,点击时将isShowMenu变为true
const emits = defineEmits(["hidden"]); // 创建一个事件
const hideMenu = () => {
emits('hidden',false);
}
const isShowMenu = ref(false);
const handle = (e) => {
isShowMenu.value = e;
};
最终实现了页面的丝滑跳转
小计
在本节课中我们使用Vant组件库进行了两个页面的开发——登入后的跳转页和个人详情页(菜单页)。 并且利用父子通讯的事件订阅模式巧妙的实现了这两个页面的丝滑跳转。
**本章要点:Vant , CSS , emits , :class="{}" **
转载自:https://juejin.cn/post/7399952279501422607