来自子组件的 v-navigation-drawer 控制状态

v-navigation-drawer controlled state from a sub-component

我有一个 v-navigation-drawer,可以通过单击子组件中的按钮打开它。

所以我将 v-model="drawer" 更改为简单的 value="drawer" 否则我会收到关于改变一个有意义的 prop 的警告(感觉就像在做一些肮脏的 angular 双向数据绑定 ^^ ).

代码如下:

layouts/default.vue:

<template>
    <Header :toggleLeftMenu="toggleLeftMenu" />
    <LeftMenu :show="showLeftMenu" :toggleLeftMenu="toggleLeftMenu" />
</template>

<script>
  export default {
    data() {
      return {
        showLeftMenu: true,
      }
    },
    methods: {
      toggleLeftMenu() {
        this.showLeftMenu = !this.showLeftMenu;
      },
    }
  }
</script>

components/layout/LeftMenu.vue:

  <v-navigation-drawer
    :value="show"
    width="300"
    clipped
    fixed
    app
  >

这个问题是抽屉可以通过点击背景关闭(在小型设备上)。我需要将背景点击插入 toggleLeftMenu 道具,但根据文档,这似乎不可能。

如何实现对组件的完全控制?这个@backdropClick 事件丢失了吗?

我尝试使用 @input,但它创建了一个无限循环,这也是有道理的。

谢谢

使用 vuetify 2.6.1.

I changed v-model="drawer" to simply value="drawer" otherwise I get a warning about mutating a prop

这不是一个正确的决定。当然你不应该使用 drawer 作为模型,但是你可以在 LeftMenu 组件中创建一个 internalDrawer prop,并保留 v-model 它在哪里。


解决您的问题的一种可能方法是将事件从两个子组件发送到其父组件。

所以让我们这样重写您的 LeftMenu 组件:

<template>
  <v-navigation-drawer v-model="internalShow" width="200" clipped fixed app>
    some drawer data
  </v-navigation-drawer>
</template>

<script>
export default {
  props: {
    show: Boolean,
  },
  data() {
    return {
      internalShow: this.show,
    };
  },
  watch: {
    show (val) {
      this.internalShow = val;
    },
    internalShow (val) {
      if (val !== this.show) {
        this.$emit("change-drawer-state");
      }
    },
  },
};
</script>

在这种情况下,每次 internalShow 状态发生变化时,都会发出一个 change-drawer-state 事件。

您的 Header 组件可以用同样的方式重写:

<template>
  <v-btn @click="$emit('change-drawer-state')">Drawer button</v-btn>
</template>

这是您的父组件的代码:

<template>
  <div>
    <Header @change-drawer-state="toggleLeftMenu" />
    <LeftMenu :show="showLeftMenu" @change-drawer-state="toggleLeftMenu" />
  </div>
</template>

<script>
import LeftMenu from "./LeftMenu";
import Header from "./Header";

export default {
  components: {
    LeftMenu,
    Header,
  },
  data() {
    return {
      showLeftMenu: false,
    };
  },
  methods: {
    toggleLeftMenu() {
      this.showLeftMenu = !this.showLeftMenu;
    },
  },
};
</script>

两个 change-drawer-state 事件处理程序调用相同的方法 - toggleLeftMenu 然后该方法更改 show 导航道具 -抽屉.

您可以测试此解决方案 in a CodeSandbox playground