webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
一、创建抽屉组件的基本结构
< view class = " drawer-container" >
< view class = " mask-container" > </ view>
< view class = " content-container" >
< slot> </ slot>
</ view>
</ view>
二、定义遮罩层、内容区域的基础样式
.drawer-container {
position : fixed;
top : 0rpx;
left : 0rpx;
right : 0rpx;
bottom : 0rpx;
z-index : 999;
.mask-container {
display : block;
position : absolute;
top : 0;
left : 0;
bottom : 0;
right : 0;
opacity : 0;
background-color : rgba ( 15, 37, 41, 0.72) ;
transition : opacity 0.3s;
}
.content-container {
position : absolute;
right : -100%;
top : 0rpx;
bottom : 0rpx;
z-index : 999;
background-color : #ffffff;
transition : right 0.3s ease;
}
}
三、JS逻辑控制显隐
javascript">import {
defineProps,
ref,
reactive,
defineExpose
} from 'vue'
const props = defineProps ( {
width : {
type : String,
default : '310px'
}
} )
const that = reactive ( {
visible : false ,
showDrawer : false
} )
let watchTimer = null
const open = ( ) => {
if ( that. visible) {
return
}
change ( 'visible' , 'showDrawer' , true )
}
const close = ( ) => {
if ( ! that. visible) {
return
}
change ( 'showDrawer' , 'visible' , false )
}
const change = ( param1, param2, status ) => {
that[ param1] = status
if ( watchTimer) {
clearTimeout ( watchTimer)
}
watchTimer = setTimeout ( ( ) => {
that[ param2] = status
} , status ? 50 : 300 )
}
defineExpose ( {
open,
close
} )
四、visible控制组件显隐,showDrawer字段动态控制样式
< view v-if = " that.visible" class = " drawer-container" >
< view class = " mask-container" :class = " {'mask-visible': that.showDrawer}" @tap = " close" > </ view>
< view :style = " {width}" class = " content-container" :class = " {'content-visible--right': that.showDrawer}" >
< slot> </ slot>
</ view>
</ view>
五、添加过渡样式
.content-visible--right {
right : 0;
}
.mask-visible {
display : block;
opacity : 1;
}
六、查看完整代码
javascript">< template>
< view v- if = "that.visible" class = "drawer-container" >
< ! -- 点击遮罩关闭抽屉 -- >
< view class = "mask-container" : class = "{'mask-visible': that.showDrawer}" @tap= "close" > < / view>
< ! -- 内容展示区域 -- >
< view : style= "{width}" class = "content-container" : class = "{'content-visible--right': that.showDrawer}" >
< slot> < / slot>
< / view>
< / view>
< / template>
< script setup>
import {
defineProps,
ref,
reactive,
defineExpose
} from 'vue'
const props = defineProps ( {
width : {
type : String,
default : '310px'
}
} )
const that = reactive ( {
visible : false ,
showDrawer : false
} )
let watchTimer = null
const open = ( ) => {
if ( that. visible) {
return
}
change ( 'visible' , 'showDrawer' , true )
}
const close = ( ) => {
if ( ! that. visible) {
return
}
change ( 'showDrawer' , 'visible' , false )
}
const change = ( param1, param2, status ) => {
that[ param1] = status
if ( watchTimer) {
clearTimeout ( watchTimer)
}
watchTimer = setTimeout ( ( ) => {
that[ param2] = status
} , status ? 50 : 300 )
}
defineExpose ( {
open,
close
} )
< / script>
< style lang= "scss" scoped>
. drawer- container {
position : fixed;
top : 0rpx;
left : 0rpx;
right : 0rpx;
bottom : 0rpx;
z- index: 999 ;
. mask- container {
display : block;
position : absolute;
top : 0 ;
left : 0 ;
bottom : 0 ;
right : 0 ;
opacity : 0 ;
background- color: rgba ( 15 , 37 , 41 , 0.72 ) ;
transition : opacity 0 . 3s;
}
. content- container {
position : absolute;
right : - 100 % ;
top : 0rpx;
bottom : 0rpx;
z- index: 999 ;
background- color: #ffffff;
transition : right 0 . 3s ease;
}
. content- visible-- right {
right : 0 ;
}
. mask- visible {
display : block;
opacity : 1 ;
}
}
< / style>