Vuetify 3 v-navigation-drawer点击外部无法关闭问题排查
问题根因
- 仅使用
:model-value做单向绑定时,temporary模式的导航抽屉点击外部/遮罩层触发关闭动作时,无法将关闭状态回写到Pinia中,全局存储的抽屉状态始终为true,因此视觉上抽屉无任何反应,控制台也不会报常规错误。 - 直接使用
v-model报错,是因为你通过Pinia getter返回的状态是只读的,v-model默认会尝试直接修改绑定值,只读属性无法被赋值因此抛出运行时错误;使用:value是Vuetify 2的旧版绑定语法,Vuetify 3不再识别该prop,因此抽屉完全无法打开。
修复步骤
1. 调整Pinia Store代码
移除不必要的私有状态+getter包装,新增专门用于设置抽屉状态的action,避免直接修改状态:
import { defineStore } from "pinia"; export const useAdminSharedStore = defineStore({ id: "admin-shared-store", state: () => ({ isOpenDrawer: false, }), actions: { toggleDrawer() { this.isOpenDrawer = !this.isOpenDrawer; }, // 新增状态设置方法,供组件回写抽屉状态 setDrawerState(open: boolean) { this.isOpenDrawer = open; } }, });
如果需要禁止外部直接修改state,可以开启Pinia的严格模式,不需要手动给状态加下划线、用getter包装成只读,多余的包装反而会阻断组件的状态同步逻辑。
2. 修改SideBar.vue的导航抽屉绑定
将v-model拆分为单向值绑定+更新事件监听,事件触发时调用store的action同步状态,不要直接给v-model绑定只读的store值:
<template> <v-navigation-drawer width="260" color="background" border="0" :model-value="adminSharedState.isOpenDrawer" @update:model-value="adminSharedState.setDrawerState" temporary > <div class="ps-6 pe-5 pt-5 pb-2"> <router-link class="d-flex align-center text-decoration-none home-link" :to="{ name: routeNames.owner }"> <img :src="logo" alt="logo" width="30" height="24" /> <p class="text-uppercase title ml-3">Meet scapes</p> </router-link> </div> <v-list class="pr-5 v-sheet" bg-color="background"> </v-list> </v-navigation-drawer> </template>
Header.vue的代码不需要修改,点击导航按钮触发toggle的逻辑可以正常生效。
修改完成后,temporary模式抽屉默认的点击外部关闭、ESC键关闭逻辑都会正常触发,触发时会自动调用setDrawerState把Pinia里的状态同步为false,抽屉就会正常关闭。
内容的提问来源于stack exchange,提问作者artak-avanesian
相关产品推荐
相关产品推荐

