如何声明嵌套的反应式组件?

时间:2019-06-24 13:05:37

标签: javascript vue.js reactive-programming

在阅读文档中的"Reactivity in Depth"时,我看到两点我不确定如何解释:

  

将纯JavaScript对象作为数据传递给Vue实例时   选项,Vue将遍历其所有属性并将其转换   使用Object.defineProperty

获取/设置

(...)

  

由于现代JavaScript的局限性(以及   Object.observe),Vue 无法检测到属性添加或   删除。由于Vue执行getter / setter转换过程   在实例初始化期间,数据中必须存在一个属性   对象,以便Vue对其进行转换并使其具有反应性。

这与嵌套对象(如

)有什么关系
[
  {
    "a": 1,
    "b": [
      {
        "c": 1
      },
      ...
    ]
  },
  {
    "a": 10,
    "b": [
      {
        "c": 10
      },
      ...
    ]
  },
  ...
]

具体来说,应如何将此类对象呈现给data()使其具有反应性?

data() {
    return {
        likeThis: [],
        orLikeThat: [{}],
        orMoreDetailed: [{a: null, b:[]}],
        orTheFullStucture: [{a: null, b:[{c: null}]}]
    }
}

1 个答案:

答案 0 :(得分:1)

我认为您误解了property addition/deletion caveat。您引用的文档第一部分中的语句对示例对象成立。如果将该对象设置为data方法返回的对象的属性,则该对象中的所有内容都是反应性的。

这是一个简单的示例,其中我已在myNestedData方法中将您的对象设置为data。我通过myNestedData[0].b[0].cv-model绑定到一个输入元素,您可以看到对该值的更改反映在myNestedData对象本身中。

Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  data() {
    return {
      myNestedData: [{
        "a": 1,
        "b": [{ 
          "c": 1
        }]
      }, {
        "a": 10,
        "b": [{
          "c": 10
        }]
      }]
    };
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input v-model="myNestedData[0].b[0].c" type="number">
  <br>
  {{ myNestedData }}
</div>


您在代码的最后一部分中给出的所有示例都是完全被动的,如上面的示例所示。仅当您尝试从这些反应数据对象中添加或删除属性时,属性添加/删除警告才起作用。

这是一个简单的示例,其中一个foo属性最初是在data方法中设置的,其值为[{ a: 'apple' }]。然后,在组件的this.foo[0].b挂钩中将'banana'设置为created。但是,由于b的{​​{1}}属性以前不存在,因此该属性不是被动的。您可以通过更改第二个输入的值(通过this.foo[0]绑定到v-model来查看)。更改该值不会更新foo[0].b中该属性的值。

foo
Vue.config.productionTip = false;
Vue.config.devtools = false;

new Vue({
  el: '#app',
  data() {
    return {
      foo: [{ a: 'apple' }]
    };
  },
  created() {
    this.foo[0].b = 'banana';
  }
});