Vue3 自定义 Drawer 抽屉组件
本次简单的展示了如何自定义一个 Drawer 抽屉组件
vue
<script lang='ts' setup>
import {ref, reactive, watch} from 'vue'
interface Props {
visible: boolean
}
const props = withDefaults(defineProps<Props>(), {
visible: false
})
const emit = defineEmits<{(e: 'update:visible', value: boolean): void}>()
const maskStyle = reactive({
display: 'none',
opacity: 0
})
const drawerStyle = reactive({
transform: 'translateX(100%)'
})
const closeDrawer = () => {
emit('update:visible', false)
}
watch(() => props.visible, (val) => {
if (val) {
maskStyle.display = 'block'
maskStyle.opacity = 0.5
drawerStyle.transform = 'translateX(0)'
} else {
maskStyle.opacity = 0
drawerStyle.transform = 'translateX(100%)'
setTimeout(() => {
maskStyle.display = 'none'
}, 1000);
}
}, {
immediate: true
})
</script>
<template>
<View @tap="closeDrawer" class="drawer-background" :style="maskStyle"></View>
<View class="drawer-container" :style="drawerStyle">
<slot />
</View>
</template>
<style>
.drawer-background {
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
transition-duration: 0.3s;
z-index: 1000;
}
.drawer-container {
position: fixed;
top: 0;
right: 0;
width: 60%;
height: 100vh;
background-color: #fff;
transition-duration: 0.3s;
transform: translateX(100%);
z-index: 1000;
}
</style>
上述代码是 taro 的小程序代码实现,主要是通过 transition-duration
来实现动画效果,通过 transform
来实现移动效果,通过 opacity
来实现透明度效果。
需要注意的是通过 transform: translateX(100%);
将抽屉组件移动到屏幕外,通过 transform: translateX(0);
将抽屉组件移动到屏幕内。
蒙版的动画不能立即使用 display: none;
来隐藏,需要通过 setTimeout
来实现,否则动画效果会没效果。
调用
vue
<script lang='ts' setup>
import { ref } from 'vue'
// 是否显示抽屉
const show = ref(false)
function open() {
show.value = true
}
</script>
<template>
<Drawer v-model:visible="show">
drawer content
</Drawer>
</template>
<style>
</style>