vue 3 中用 ref 控制抽屉菜单动画:通过 ref 管理布尔状态,结合 触发 css 滑入/滑出动画,并用 nexttick 和 dom ref 实现聚焦、滚动锁定等交互,支持钩子函数处理动画完成逻辑。

在 Vue 3 中,用 ref 控制抽屉菜单的打开/关闭动画,核心是结合 ref 管理状态 + <transition></transition> 或 <transition-group></transition-group> 驱动 CSS 动画,并通过 ref 触发重排或监听状态变化来精确控制动画时机。
用 ref 控制抽屉显隐状态
定义一个响应式布尔 ref 来表示抽屉是否展开:
import { ref } from 'vue'
const isDrawerOpen = ref(false)
const toggleDrawer = () => {
isDrawerOpen.value = !isDrawerOpen.value
}
这个 ref 将作为 v-if 或 v-show 的判断依据,也是 <transition></transition> 的触发开关。
配合 实现进入/离开动画
抽屉通常需要滑入/滑出效果(如从右向左),推荐使用 v-if + <transition></transition>,确保 DOM 完全挂载/卸载以准确触发动画:
<transition name="drawer-slide"><div v-if="isDrawerOpen" class="drawer">
<slot></slot>
</div>
</transition>
CSS 动画需定义 .drawer-slide-enter-active 和 .drawer-slide-leave-active 的过渡属性,例如:
.drawer-slide-enter-active,
.drawer-slide-leave-active {
transition: transform 0.3s ease, opacity 0.2s ease;
}
.drawer-slide-enter-from {
transform: translateX(100%);
opacity: 0;
}
.drawer-slide-enter-to {
transform: translateX(0);
opacity: 1;
}
.drawer-slide-leave-from {
transform: translateX(0);
opacity: 1;
}
.drawer-slide-leave-to {
transform: translateX(100%);
opacity: 0;
}
需要 JS 动画控制时:用 ref 获取 DOM 并手动触发动画
如果动画逻辑较复杂(如滚动锁定、键盘 ESC 关闭、点击遮罩关闭),可用 ref 获取抽屉 DOM 元素,在状态变更后执行操作:
import { ref, onMounted, onUnmounted } from 'vue'
const drawerRef = ref(null)
// 打开时聚焦、加 body 锁定
const openDrawer = () => {
isDrawerOpen.value = true
nextTick(() => {
drawerRef.value?.focus()
document.body.style.overflow = 'hidden'
})
}
// 关闭时恢复
const closeDrawer = () => {
isDrawerOpen.value = false
document.body.style.overflow = ''
}
// ESC 关闭
const handleKeydown = (e) => {
if (e.key === 'Escape' && isDrawerOpen.value) {
closeDrawer()
}
}
onMounted(() => {
document.addEventListener('keydown', handleKeydown)
})
onUnmounted(() => {
document.removeEventListener('keydown', handleKeydown)
})
注意:必须用 nextTick 确保 DOM 渲染完成后再操作 drawerRef.value。
进阶:动画完成后的回调处理
若需在动画结束后执行某些逻辑(如销毁子组件、重置表单),可利用 <transition></transition> 的钩子:
<transition><div v-if="isDrawerOpen" ref="drawerRef" class="drawer">
<slot></slot>
</div>
</transition>
对应方法中可访问 drawerRef.value,例如:
const onAfterEnter = () => {
console.log('抽屉已完全展开')
// 可触发子组件初始化、加载数据等
}
const onAfterLeave = () => {
console.log('抽屉已完全收起')
// 可重置内部表单、释放资源
}
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










