标题栏与菜单栏

渲染标题栏与菜单栏

标题栏和菜单栏分别位于最上与最下,浮动在电子书上方,有对应的图标

image-20240312184349547

引入图标

我们在之前已经把图标文件放入了fonts文件夹下,在页面中可以直接引用<spen class="icon-back"></spen>

标题栏

层级:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="title-wrapper">
<div class="left">
<spen class="icon-back icon"></spen>
</div>
<div class="right">
<div class="icon-wrapper">
<spen class="icon-cart icon"></spen>
</div>
<div class="icon-wrapper">
<spen class="icon-person icon"></spen>
</div>
<div class="icon-wrapper">
<spen class="icon-more icon"></spen>
</div>
</div>
</div>

title-wrapper使用flex布局分为左右两侧,右边有3个图标,可以继续嵌套使用flex布局

样式:

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
.title-wrapper {
position: absolute;
top: 0;
left: 0;
z-index: 101;
display: flex;
width: 100%;
height: px2rem(48);
background: white;
box-shadow: 0 px2rem(8) px2rem(8) rgba(0, 0, 0, .15);
.left {
flex: 0 0 px2rem(60);
// 引入global.scss的居中
@include center;
}
.right {
flex: 1;
display: flex;
justify-content: flex-end;
.icon-wrapper {
flex: 0 0 px2rm(40);
width: px2rem(40);
@include center;
.icon-cart{
font-size: px2rem(22);
}
}
}
}

菜单栏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="menu-wrapper " v-show="ifTitleAndMenuShow">
<div class="icon-wrapper">
<span class="icon-menu icon"></span>
</div>
<div class="icon-wrapper">
<span class="icon-progress icon"></span>
</div>
<div class="icon-wrapper">
<span class="icon-bright icon"></span>
</div>
<div class="icon-wrapper">
<span class="icon-a icon">A</span>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 底部菜单样式
.menu-wrapper {
position: absolute;
bottom: 0;
left: 0;
z-index: 101;
display: flex;
width: 100%;
height: px2rem(48);
background: white;
box-shadow: 0 px2rem(-8) px2rem(8) rgba(0, 0, 0, .15);
.icon-wrapper {
flex: 1;
@include center;
icon-progress {
font-size: px2rem(24);
}
}

}

标题栏和菜单栏的显示和隐藏

使用v-show实现在点击屏幕中间实现标题栏和菜单栏的显示和隐藏

先添加一个变量来记录显示状态

ifTitleAndMenuShowfalse时隐藏,我们默认隐藏

1
2
3
4
5
6
7
export default {
data () {
return {
ifTitleAndMenuShow: false
}
},
}

在center元素中添加一个点击事件

1
<div class="center" @click="toggleTitleAndMenu"></div>

点击后调用toggleTitleAndMenu方法,翻转ifTitleAndMenuShow

1
2
3
toggleTitleAndMenu () {
this.ifTitleAndMenuShow = !this.ifTitleAndMenuShow
},

使用v-show实现示和隐藏

title-wrapper元素中添加v-show属性

v-show属性用于根据表达式的真假值来动态地显示或隐藏元素

1
<div class="title-wrapper" v-show="ifTitleAndMenuShow">

这样子标题栏就实现了显示和隐藏,菜单栏同理

显示和隐藏的过渡动画

使用transition属性来实现

transition动画原理

  • 使用v-show动态显示或隐藏元素时,会触发过渡动画
  • transition需要指定name,并包裹一个包含V-show的div
  • vue会为transition包裹的div动态添加class,共6种

image-20240312164607906

实现过度动画

以上方的标题栏为例:

添加transition包裹需要动画的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<transition name="slide-down">
<div class="title-wrapper" v-show="ifTitleAndMenuShow">
<div class="left">
<spen class="icon-back icon"></spen>
</div>
<div class="right">
<div class="icon-wrapper">
<spen class="icon-cart icon"></spen>
</div>
<div class="icon-wrapper">
<spen class="icon-person icon"></spen>
</div>
<div class="icon-wrapper">
<spen class="icon-more icon"></spen>
</div>
</div>
</div>
</transition>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 隐藏到显示的过渡动画
.slide-down-enter,
.slide-down-leave-to {
transform: translate3d(0, -100%, 0);
}

.slide-down-enter-to,
.slide-down-leave {
transform: translate3d(0, 0, 0);
}

.slide-down-enter-active,
.slide-down-leave-active{
transition: all .3s linear;
}
  • .slide-down-enter.slide-down-leave-to 类定义了进入过渡开始时和离开过渡结束时元素的初始状态。在这里,transform 属性被设置为将元素向上移动100%的距离,即从视图顶部移出。
  • .slide-down-enter-to.slide-down-leave 类定义了进入过渡结束时和离开过渡开始时元素的最终状态。在这里,transform 属性被设置为将元素移动到原始位置,即视图顶部。
  • .slide-down-enter-active.slide-down-leave-active 类定义了进入和离开过渡时元素的动画效果。在这里,transition 属性设置了动画效果为线性过渡,持续时间为0.3秒。

抽象到global中

因为上下都需要这段动画,这样子写太繁琐,可以整合到global中

注意下方的菜单栏是下移动100%的距离,所以单独列出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 隐藏到显示的过渡动画
.slide-down-enter,
.slide-down-leave-to {
transform: translate3d(0, -100%, 0);
}

.slide-up-enter,
.slide-up-leave-to {
transform: translate3d(0, 100%, 0);
}

.slide-down-enter-to,
.slide-down-leave,
.slide-up-enter-to,
.slide-up-leave {
transform: translate3d(0, 0, 0);
}

.slide-down-enter-active,
.slide-down-leave-active,
.slide-up-enter-active,
.slide-up-leave-active {
transition: all .3s linear;
}