如何正确设置 Vuetify 框架的两个导航抽屉?

How correctly to set two navigation drawer of Vuetify framework?

在我的 Vue.JS 应用程序中,我尝试使用两个 v-navigation-drawerVuetify 框架。出于某种原因,我的下一个代码引发了一个错误。在我的例子中,每个侧边栏都在一个单独的组件中。如何修复此类错误?

错误:

vue.esm.js?efeb:628 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "open"

BaseLayout.vue:

<template>
  <div>
    <v-app-bar app>
      <v-btn
        icon
        @click.stop="openLeftNavigationDrawer=!openLeftNavigationDrawer">
        <v-icon>mdi-map-clock-outline</v-icon>
      </v-btn>

      <v-spacer></v-spacer>

      <v-btn
        icon
        @click.stop="openRightNavigationDrawer=!openRightNavigationDrawer">
        <v-icon>mdi-filter</v-icon>
      </v-btn>
    </v-app-bar>

    <left-navigation-drawer
      :open="openLeftNavigationDrawer">
    </left-navigation-drawer>

    <right-navigation-drawer
      :open="openRightNavigationDrawer">
    </right-navigation-drawer>

    <v-content style="padding:unset!important;">
      <slot></slot>
    </v-content>
  </div>
</template>

<script>
import LeftNavigationDrawer from '../elements/LeftNavigationDrawer'
import RightNavigationDrawer from '../elements/RightNavigationDrawer'

export default {
  name: 'BaseLayout',
  components: {
    LeftNavigationDrawer,
    RightNavigationDrawer
  },
  data: function () {
    return {
      openLeftNavigationDrawer: false,
      openRightNavigationDrawer: false
    }
  }
}
</script>

LeftNavigationDrawer.vue:

<template>
  <v-navigation-drawer
    v-model="open"
    absolute
    left>
  </v-navigation-drawer>
</template>

<script>
export default {
  name: 'LeftNavigationDrawer',
  props: {
    open: false
  }
}
</script>

RightNavigationDrawer.vue:

<template>
  <v-navigation-drawer
    v-model="open"
    absolute
    right>
  </v-navigation-drawer>
</template>

<script>
export default {
  name: 'RightNavigationDrawer',
  props: {
    open: false
  }
}
</script>

在你的LeftNavigationDrawerRightNavigationDrawer组件中,当你写v-model="open"时,它允许v-navigation-drawer组件改变open的值。

但是,在 VueJS 中,不允许组件更改其属性的值。只有 parent 可以做到这一点。由于 open 是一个 prop 而 v-navigation-bar 正在尝试更改它,您会看到错误 Avoid mutating a prop....

为了修复它,您可以在发送到 v-navigation-drawer 的组件中定义一个 data。像这样:

// RightNavigationDrawer.vue/LeftNavigationDrawer
<template>
  <v-navigation-drawer
    v-model="drawerOpen"
    @input="onInput"
    absolute
    right>
  </v-navigation-drawer>
</template>

<script>
export default {
  name: 'RightNavigationDrawer',
  props: {
    open: {
       type: Boolean,
       default: false
    }

  },
 data(){
   return {
      drawerOpen: this.open
   }
 },
 watch:{
   open(newVal){
      this.drawerOpen = newVal
   }
 },
 methods:{
   onInput(isOpen){
      this.$emit('drawerOpened', isOpen)
   }
 }
}
</script>
  • 数据drawerOpen存储Vuetify的v-navigation-drawer是否打开
  • watch over open 允许你在 open 道具改变时改变抽屉状态(Parent 到 Child 通信)
  • @input 处理程序允许您将新的抽屉状态发送到 parent 组件(Child 到 Parent 通信)

一旦您更改了左侧和右侧导航抽屉组件,您的 BaseLayout.vue 将需要侦听 drawerOpened 事件。

// BaseLayout.vue
<template>
  <div>
    <v-app-bar app>
      <v-btn
        icon
        @click.stop="openLeftNavigationDrawer=!openLeftNavigationDrawer">
        <v-icon>mdi-map-clock-outline</v-icon>
      </v-btn>

      <v-spacer></v-spacer>

      <v-btn
        icon
        @click.stop="openRightNavigationDrawer=!openRightNavigationDrawer">
        <v-icon>mdi-filter</v-icon>
      </v-btn>
    </v-app-bar>

    <left-navigation-drawer
      :open="openLeftNavigationDrawer"
      @drawer-opened="handleDrawerChange("left", $event)"   // Add these event handlers
    >
    </left-navigation-drawer>

    <right-navigation-drawer
      :open="openRightNavigationDrawer"
      @drawer-opened="handleDrawerChange("right", $event)"
    >
    </right-navigation-drawer>

    <v-content style="padding:unset!important;">
      <slot></slot>
    </v-content>
  </div>
</template>

<script>
import LeftNavigationDrawer from '../elements/LeftNavigationDrawer'
import RightNavigationDrawer from '../elements/RightNavigationDrawer'

export default {
  name: 'BaseLayout',
  components: {
    LeftNavigationDrawer,
    RightNavigationDrawer
  },
  data: function () {
    return {
      openLeftNavigationDrawer: false,
      openRightNavigationDrawer: false
    }
  },
  methods:{
    handleDrawerChange(type, isOpen){
       if(type === "left"){
          this.openLeftNavigationDrawer = isOpen
       }else{
          this.openRightNavigationDrawer = isOpen
       }
    }

  }
}
</script>

  • 在您的 HTML 中,您监听 drawer-opened 事件。
  • 在事件处理程序中,您传递了 2 个参数:一个是抽屉是左边还是右边。另一个参数是从组件接收到的值。
  • 根据抽屉是左还是右,您更改BaseLayout.vue中适当数据的值