在阅读文档中的"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}]}]
}
}
答案 0 :(得分:1)
我认为您误解了property addition/deletion caveat。您引用的文档第一部分中的语句对示例对象成立。如果将该对象设置为data
方法返回的对象的属性,则该对象中的所有内容都是反应性的。
这是一个简单的示例,其中我已在myNestedData
方法中将您的对象设置为data
。我通过myNestedData[0].b[0].c
将v-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';
}
});