侧边栏抽屉通过 emit 通知父组件关闭遮罩层,核心是子组件触发事件、父组件监听并统一控制显隐状态;推荐用 v-model 实现双向绑定,抽屉内遮罩层 @click 触发 update:modelValue 事件,内容区需 @click.stop 防止冒泡,可选监听 Esc 键关闭。
侧边栏抽屉通过 emit 通知父组件关闭遮罩层,核心是子组件触发事件、父组件监听并控制显隐状态。关键在于父子职责分明:抽屉只负责“我被点了关闭”,不直接操作遮罩层;遮罩层的显示/隐藏由父组件统一管理。
推荐使用 v-model 语义化双向绑定(本质是 value prop + input 或 update:modelValue 事件),更简洁清晰:
:model-value="drawerVisible",监听 @update:model-value="val => drawerVisible = val"
:visible="drawerVisible" + @close="drawerVisible = false"
<div class="mask" v-show="drawerVisible">)与抽屉共用同一响应式变量抽屉内部的遮罩层(通常为全屏半透明 div)应绑定 @click,并触发自定义事件:
<div class="drawer-mask" @click="$emit('update:modelValue', false)"></div>
<div class="drawer-mask" @click="$emit('close')"></div>
如果抽屉内容区域点击也意外关闭,需阻止事件冒泡:
@click.stop,例如:<div class="drawer-content" @click.stop>...
.stop,它就是关闭触发源@click.self,因为遮罩层通常无子元素,且 self 对全屏 div 意义不大提升体验,抽屉挂载后监听 keydown.escape:
onMounted 中添加:document.addEventListener('keydown', handleEsc)
const handleEsc = (e) => e.key === 'Escape' && $emit('update:modelValue', false)onUnmounted 中移除监听,避免内存泄漏