hldy_app/component/public/Drawer.vue

138 lines
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!-- 遮罩层display v-show 控制opacity overlay-show 类控制 -->
<view v-show="isVisible" :class="['overlay', { 'overlay-show': isVisible }]" @click="whiteDrawer" />
<!-- 抽屉 -->
<view :class="['drawer', { 'drawer-open': isVisible }]" :style="drawerStyle">
<view class="drawer-content">
<!-- 抽屉中间的半圆 -->
<view v-show="isVisible && canclose" class="drawer-content-circle" @click="whiteDrawer">
<image class="drawer-img" src="/static/index/zuoyuan.png" />
</view>
<!-- 抽屉内容 -->
<slot />
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
defineProps,
computed
} from 'vue'
// 控制抽屉显示隐藏
const isVisible = ref(false)
// 接收父组件传入的宽度百分比
const props = defineProps({
widNumber: {
type: Number,
default: 85
},
canclose: {
type:Boolean,
default:true
}
})
// 仅动态设置宽度,位置由 transform 控制
const drawerStyle = computed(() => ({
width: `${props.widNumber}%`
}))
// 对外暴露打开方法
function openDrawer() {
isVisible.value = true
}
// 点击空白关闭方法
function whiteDrawer() {
if(props.canclose){
isVisible.value = false
}
}
// 对外暴露关闭方法
function closeDrawer() {
isVisible.value = false
}
defineExpose({
openDrawer,
closeDrawer
})
</script>
<style lang="less" scoped>
/* 遮罩层样式 */
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
z-index: 999;
will-change: opacity;
transition: opacity 0.3s ease;
opacity: 0;
display: block;
/* 由 v-show 控制 */
}
/* 当 isVisible 为 true 时,添加 overlay-show 类,触发遮罩渐显 */
.overlay-show {
opacity: 1;
}
/* 抽屉整体样式 */
.drawer {
position: fixed;
top: 0;
right: 0;
height: 100vh;
background: #fff;
z-index: 1000;
border-top-left-radius: 80rpx;
border-bottom-left-radius: 80rpx;
/* 使用 transform 做动画,避免布局重排 */
transform: translateX(100%);
transition: transform 0.4s ease;
will-change: transform;
}
/* 抽屉打开时 */
.drawer-open {
transform: translateX(0);
}
.drawer-content {
position: relative;
width: 100%;
height: 100%;
}
.drawer-content-circle {
position: absolute;
top: calc(50% - 55rpx);
left: -40rpx;
width: 100rpx;
height: 110rpx;
border-radius: 50%;
z-index: -1;
background: linear-gradient(to bottom, #dfecfa, #c9dbee);
display: flex;
align-items: center;
clip-path: inset(0 60% 0 0);
}
.drawer-img {
width: 25rpx;
height: 25rpx;
margin-left: 10rpx;
transform: rotate(180deg);
}
</style>