vue.js $watch 对象数组
Posted
技术标签:
【中文标题】vue.js $watch 对象数组【英文标题】:vue.js $watch array of objects 【发布时间】:2016-03-20 22:17:32 【问题描述】:mounted: function()
this.$watch('things', function()console.log('a thing changed'), true);
things
是一个对象数组[foo:1, foo:2]
$watch
检测何时添加或删除对象,但不会检测对象上的值何时更改。我该怎么做?
【问题讨论】:
我个人认为最好的答案在这里:reactgo.com/vue-watch-array-of-objects 【参考方案1】:您可以使用$watch('arr.0', () => )
或$watch('dict.keyName', () => )
独立观察数组或字典中的每个元素的变化
来自https://vuejs.org/v2/api/#vm-watch:
注意:当改变(而不是替换)一个对象或数组时, 旧值将与新值相同,因为它们引用 相同的对象/数组。 Vue 不保留预突变值的副本。
但是,您可以独立地迭代 dict/array 和 $watch 每个项目。 IE。 $watch('foo.bar')
- 这会监视对象 'foo' 的属性 'bar' 的变化。
在这个例子中,我们观察 arr_of_numbers 中的所有项目,以及 arr_of_objects 中所有项目的 'foo' 属性:
mounted()
this.arr_of_numbers.forEach( (index, val) =>
this.$watch(['arr_of_numbers', index].join('.'), (newVal, oldVal) =>
console.info("arr_of_numbers", newVal, oldVal);
);
);
for (let index in this.arr_of_objects)
this.$watch(['arr_of_objects', index, 'foo'].join('.'), (newVal, oldVal) =>
console.info("arr_of_objects", this.arr_of_objects[index], newVal, oldVal);
);
,
data()
return
arr_of_numbers: [0, 1, 2, 3],
arr_of_objects: [foo: 'foo', foo:'bar']
【讨论】:
【参考方案2】:如果有人需要获取数组中已更改的项目,请检查:
JSFiddle Example
帖子示例代码:
new Vue(
...
watch:
things:
handler: function (val, oldVal)
var vm = this;
val.filter( function( p, idx )
return Object.keys(p).some( function( prop )
var diff = p[prop] !== vm.clonethings[idx][prop];
if(diff)
p.changed = true;
)
);
,
deep: true
,
...
)
【讨论】:
每次更新时对整个数组进行 diff 似乎有点过分。我想知道是否有办法让 Vue 直接告诉我更新了哪个元素...【参考方案3】:有一种更简单的方法可以在没有深度观察的情况下观察 Array 的项目:使用计算值
el: "#app",
data ()
return
list: [a: 0],
calls: 0,
changes: 0,
,
computed:
copy () return this.list.slice() ,
,
watch:
copy (a, b)
this.calls ++
if (a.length !== b.length) return this.onChange()
for (let i=0; i<a.length; i++)
if (a[i] !== b[i]) return this.onChange()
,
methods:
onChange ()
console.log('change')
this.changes ++
,
addItem () this.list.push(a: 0) ,
incrItem (i) this.list[i].a ++ ,
removeItem(i) this.list.splice(i, 1)
https://jsfiddle.net/aurelienlt89/x2kca57e/15/
我们的想法是构建一个计算值copy
,它恰好具有我们想要检查的内容。计算值很神奇,只将观察者放在实际读取的属性上(这里,list
的项目在list.slice()
中读取)。 copy
watcher 中的检查实际上几乎没有用(可能除了奇怪的极端情况),因为计算值已经非常精确。
【讨论】:
【参考方案4】:你应该传递一个对象而不是布尔值作为options
,所以:
mounted: function ()
this.$watch('things', function ()
console.log('a thing changed')
, deep:true)
或者您可以像这样将观察者设置为 vue
实例:
new Vue(
...
watch:
things:
handler: function (val, oldVal)
console.log('a thing changed')
,
deep: true
,
...
)
[demo]
【讨论】:
很好,这是一个迁移问题。在 vue 的最后一个版本中,我使用true
作为最后一个参数的意思是 deep
。泰!
为我工作。谢谢!以上是关于vue.js $watch 对象数组的主要内容,如果未能解决你的问题,请参考以下文章