为什么prop在动态组件中没有反应?

时间:2019-07-04 08:35:22

标签: javascript vue.js vue-component

我在另一个插槽中注入了一个动态组件,并将props对象传递给它。但是,当我更新与属性(dotnet build --configuration Release /p:Version=0.1.19185.10 )相关联的数据(数组)时,该属性不会在组件内部进行更新。

似乎我处理了两个不同的对象,但是数组是由引用传递的,不是吗?

这是主要组成部分

dataT: this.tableData

当我在主要组件中修​​改 <template> <Button @click="addWindows"></Button> <Window v-for="window in windows" :key="window.id"> <component :is="window.name" v-bind="window.props" @onDeleteRow="handleDeleteRow"></component> </Window> </template> <script> export default{ data(){ return{ windows:[], tableData:[ { id: '0', name: 'dog' }, { id: '1', name: 'cow' }, { id: '2', name: 'cat' } ] } }, methods:{ addWindows(){ this.windows = [ { id: 0, name: 'Component1', props: { dataT: this.tableData } }, { id: 1, name: 'Component2', props: {} }]; }, handleDeleteRow(id){ this.tableData = this.tableData.filter(r => r.id != id); } } } </script> 时,我希望在dataT中更新Component1道具。

2 个答案:

答案 0 :(得分:2)

基于早期版本问题的原始答案

如果将windows设为计算属性,则它可以取决于tableData

export default {
  data() {
    return {
      tableData: [
        {
          id: '0',
          name: 'dog'
        },
        {
          id: '1',
          name: 'cow'
        },
        {
          id: '2',
          name: 'cat'
        }
      ]
    }
  },
  computed: {
    windows () {
      return [
        {
          id: 0,
          name: 'Component1',
          props: {
            dataT: this.tableData
          }
        }, {
          id: 1,
          name: 'Component2',
          props: {}
        }
      ]
    }
  }
}

如果您不能全部将其设为计算属性,例如因为您需要能够对其进行修改,然后将其保留为data并仅使用计算属性创建模板中所需的数组。在这种情况下,计算出的属性将只是将数据的不同部分合并为正确的形式。

在您的原始代码中,行dataT: this.tableData将不起作用,因为this.tableData尚不存在,只是undefined。这里没有惰性评估,它需要在到达该点时解析为正确的对象。

即使它能够访问正确的对象,也无济于事,因为在handleDeleteRow中,您正在重新分配tableData指向另一个对象。传递“按引用”与您用来标识对象的名称无关,它引用内存中的引用。

顺便说一句,v-on也支持对象语法,就像v-bind一样,因此您可以以类似的方式使onDeleteRow为可选。

根据已编辑的问题进行更新

addWindows中编写时:

props: {
    dataT: this.tableData
}

这会将this.tableData当前值分配给dataT。该当前值将是一个数组,并且由于数组是引用类型,所以无论使用什么标识符对其进行引用,对该数组所做的任何修改都将适用。

但是,这行...

this.tableData = this.tableData.filter(r => r.id != id);

...不会修改该数组。相反,它为this.tableData分配了一个全新的数组。这对dataT所引用的数组没有影响。

有几种方法可以解决此问题,包括使用计算属性。但是,属性获取器可能会提供方便的技巧:

addWindows () {
  const vm = this;

  this.windows = [
    {
      id: 0,
      name: 'Component1',
      props: {
        get dataT () {
          return vm.tableData
        }
      }
    },
    {
      id: 1,
      name: 'Component2',
      props: {}
    }
  ];
}

这将始终计算为tableData的当前值。通过这种额外的间接操作,Vue的反应性应该很好,它只是将其视为等同于直接访问tableData

答案 1 :(得分:1)

TL; DR

问题在于您的绑定。使用以下内容:

<component 
    :is="window.name"
    :dataT="window.props.dataT"
    @onDeleteRow="handleDeleteRow">
</component>

说明

v-bind属性指定将什么属性绑定到什么值(或引用)。在您的情况下,您没有指定要绑定到哪些prop的值,因此没有按预期方式绑定组件prop。