首页 > 解决方案 > 为什么这个子事件不更新父级(Vue)中的状态

问题描述

我有一个名为 customize-charts 的组件,其中包含一个 Vuetify 抽屉:

<template>
  <v-col>
    <v-btn style="float: right" class="mr-4 mt-2" small @click="toggleCustomize"  v-if="!open">Customize Dashboard</v-btn>
    <v-navigation-drawer
      v-model="open"
      temporary
      absolute
      right
      style="width: 25vw"
    >
      <span>draw contents</span>
      <v-divider />
    </v-navigation-drawer>
  </v-col>
</template>
<script>
export default {
  props: {
    data: {
      type: Array,
      default () { return [] }
    },
    open: {
      type: Boolean,
      default () { return false }
    }
  },
  data () {
    return {
      draggingItem: null
    }
  },
  methods: {
    toggleCustomize () {
      this.$emit('open')
    }
  }
}
</script>

如您所见,抽屉正在监听的布尔值称为“open”,它是从父级传递的:

  <customize-charts v-if="chartCards.length" :data="chartCards" :open="customizePanel" @updateorder="updateOrder" @toggleshow="toggleShow" @open="customizePanel=!customizePanel"/> 

父级还具有以下内容:

{
  data () {
    return {
       customizePanel: false,
    }
  }
} 

我的问题是,当open调用自定义事件(@open="customizePanel=!customizePanel")时,抽屉打开,但是当它关​​闭时(用户单击抽屉外),它没有设置customizePanel为 false。我怎样才能做到这一点?

标签: javascriptvue.jsvuetify.js

解决方案


问题是您正在使用open带有v-model. 道具被设计为仅作为一种数据绑定方式(将数据从父级传递给子级),并且您不应该在子组件中修改它的值(如果您打开浏览器开发工具,我相信您会看到来自 Vue 的很好的警告,准确地解释了这一点)因为新值将在下一次重新渲染时被父值覆盖...

只需将计算属性用于v-model

computed: {
  isOpen: {
   get() { return this.open }, // return prop value
   set() { this.$emit('open') } // emit event and change prop value in parent's event handler - new value gets propagated back to child
  }
}

推荐阅读