以下是我的代码的简化版本:
Vue.component('entry', {
template: '\
<div>\
<label>Name: <input type="text" v-model="entry.name"></label>\
</div>\
',
props: ['entry']
});
Vue.component('entries', {
template: '\
<div>\
<entry v-for="entry in entries" :entry="entry"></entry>\
<pre>{{ combined }}</pre>\
</div>\
',
props: ['entries'],
computed: {
combined: function() {
combined = [];
this.entries.forEach(function(entry) {
combined.push(entry.name);
});
return combined.join("\n");
}
}
});
var entries = [
{name: "Entry 1"},
{name: "Entry 2"},
{name: "Entry 3"}
];
JSFiddle:https://jsfiddle.net/msw3Lx98/3/
顶级组件(entries
)获取对象列表,并为每个组件创建一个子组件(entry
)。子组件将条目数据绑定到输入。
当用户通过键入其中一个输入来修改数据时,顶级组件需要将更新后的combined
值推送到单独的代码位。
我对观察者模型的理解是,如果顶级组件监视entries
,它可以检测到列表中添加或删除内容的时间,但是当 中的数据时进入变化。
但是,顶级组件显然确实以某种方式看到此类更改,因为当用户键入输入时,combined
的值会更新。
有没有“正确”的方法来检测这种变化?
以下是我探索过的几个选项:
updated
方法。在该方法中,发出自定义事件,并在父级中处理此事件。这是相当尴尬的,我认为它不会很好地扩展。beforeUpdate
方法 - 只要子组件发生更改,就会运行此(但不是updated
)。我不确定为什么,它对我来说闻不对。combined
属性。我对这项工作感到惊讶,但确实如此。这似乎是最直接的选择,但是从Vue文档来看,计算属性是可以观察的并不明显,所以我不愿意依赖它。答案 0 :(得分:1)
VueJS的承诺之一是它允许开发人员在考虑业务逻辑时正常编码,而框架使用 Reactivity system 来处理性能。
VueJS通过在实例化组件时定义已知对象和数组上的getter和setter来实现此目的。
这是一个更新的小提琴(从您的版本分叉):https://jsfiddle.net/6wkyfxs6/3/
正如您所看到的,我已经为addNewEntry
添加了一个方法,允许您添加&#34;元素4&#34;列表。
前3个元素具有观察者方法并不奇怪,因为它是在Vue实例化时构造的。但是如果你添加&#34;元素4&#34;在我最初没有出现的新小提琴中,即使它被观察到并且通知了变化。这就是反应系统的工作原理。
在更深入的检查中,如果您在条目组件中设置window.entries = this.entries
并检入控制台,您会注意到它顶部有一个观察者方法(entries.__ob__
)水平。这是一个截图(取自谷歌Chrome中的本地版本,而不是jsFiddle):
与使用脏检查的Angular 1.x不同,这是Vue用来更新和通知自身整体数组中的更改的内容。因此,只要您在Vue中更改某些内容, Reactivity System 就会触发并设置所有新对象和修改对象的观察者(以及getter / setter)。
如果直接在javascript中添加或更改对象,则不会触发反应系统。特别是在数组的情况下(如您的示例所示),此处显示了一些注意事项:https://vuejs.org/guide/list.html#Caveats,但您的示例避开了这些警告。
总之,VueJS允许像我们这样的开发人员在编写业务逻辑时正常编写代码,同时负责性能优化。除非您遇到一些问题,否则我认为您不应该使用任何updated
或beforeUpdate
方法 - 在这种情况下,首选应该是提交错误报告而不是工作-arounds。