popup弹窗组件
废话不多说,先上代码:
<template>
<view>
<view class="_popup" :class="popupClass">
<view class="_mask" @tap.stop="$emit('hide')">
<view class="_body" @tap.stop="showP" :style="'height:'+bodyHeight+'rpx;'">
<slot/>
</view>
</view>
</view>
</view>
</template>
<script>
export default{
props:{
popupClass:{
type:String,
default:'none'
},
bodyHeight:{
type:Number,
default:650,
}
},
methods:{
showP(){
// 空事件防止点击穿透
}
}
}
</script>
<style>
._popup,._mask{
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
._popup{
z-index: 2000;
}
._mask{
z-index: 2002;
background-color: rgba(0,0,0,0.5);
}
._popup ._body{
position: fixed;
bottom: 0;
width: 92%;
padding: 0 4%;
height: 650rpx;
background-color: #FFFFFF;
display: flex;
flex-direction: column;
border-radius: 15rpx 15rpx 0 0;
z-index: 2005;
}
._popup.show{
display: block;
}
._popup.hide{
display: block;
}
._popup.none{
display: none;
}
.show ._mask{
animation: showMask 0.2s linear both;
}
.show ._body{
animation: showBody 0.2s linear both;
}
.hide ._mask{
animation: hideMask 0.2s linear both;
}
.hide ._body{
animation: hideBody 0.2s linear both;
}
@keyframes showMask{
0%{ opacity: 0;}
100%{ opacity: 1;}
}
@keyframes showBody{
0%{ transform: rotateY(0);}
100%{ transform: rotateY(-100%);}
}
@keyframes hideBody{
0%{ transform: rotateY(-100%);}
100%{ transform: rotateY(0);}
}
@keyframes hideMask{
0%{ opacity: 1;}
100%{opacity: 0;}
}
</style>
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
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
调用:
<template>
<popup ref="popupCtrl" :popupClass="popupStatus"></popup>
</tempplate>
<script>
export default {
data() {
return {
popupStatus: 'none'
}
},
methods: {
showPopup() {
this.popupStatus = 'show';
//this.$refs.popupCtrl.show();
},
hidePopup() {
this.popupStatus = 'hide';
setTimeout(() => {
this.popupStatus = 'none';
}, 200);
////this.$refs.popupCtrl.hide();
}
}
}
</script>
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
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
如上面代码所示,弹窗分为三层:_popup包裹层、 _mask遮罩层、_body内容层。实现原理很简单,就是对遮罩和内容进行显示隐藏控制,重点在于对组件隐藏显示时动画的播放。
这里借助于display属性控制弹窗显示、隐藏,外部延迟修改popupClass属性即可实现动画播放。也可以在组件内部自己实现延迟修改事件,外部调用事件,同样可以实现动画播放。
上次更新: 2025/09/05, 8:09:00