You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:48:22