Vue 是一种反应式语言,这意味着当数据发生变化时,我们可以自动在 HTML 中表示它自己。为了帮助我们解决这个问题,我们可以在 vue 中使用观察者来观察数据的变化,然后对 HTML 做一些事情,或者向用户发送有关它的消息。
这适用于简单的数据集,但如果我们开始拥有比一层更深的数据,则很难正确地观察它的变化。
在 Vue 中观察嵌套数据的变化#
要稍微了解这个问题,我们需要了解观察者在 Vue 中是如何工作的。Vue 只监视浅变化例如,下面,我们监视 中的变化count
,以及console.log
那些变化:
<script>
export default {
data() {
return {
count: 1
}
},
watch: {
count(data) {
console.log(data);
}
}
}
</script>
<template>
<h1></h1>
<button @click="++this.count">
Click Me
</button>
</template>
每次用户点击按钮时,我们++this.count
和我们的观察者都会观察count
. 然后它会console
记录数据,因此我们可以看到新的计数值。这意味着每次单击按钮时,count 的值都会显示在控制台日志中。
然而,浅变化意味着 Vue 只检查该属性值的变化。如果我们有超过一级深度的数据,Vue 将不会检查更新。例如,count.number
下面的更新不会触发我们的观察器count
,因为 Vue 根本不会检查任何比 更深的变化count
:
data() {
return {
count: {
number: 1,
type: 'number'
}
},
watch: {
// This doesn't get triggered when count.number!
count(data) {
console.log(data);
}
}
}
相反,我们需要具体提及哪个元素正在发生变化。我们可以count.number
通过改变我们的观察者来继续观察上面的变化count.number
:
data() {
return {
count: {
number: 1,
type: 'number'
}
},
watch: {
// This gets triggered when count.number changes!
"count.number" : function(data) {
console.log(data);
}
}
}
使用上面的方法,我们可以很容易地检查属性中属性的变化,以便我们可以触发适当的观察者,但它可能会变得混乱。如果我们想简单地观察任何count
变化,我们需要使用deep属性。
使用 deep 属性#
deep 属性可以添加到任何观察者,它强制 Vue 观察特定数据属性中的任何变化。这意味着我们必须用watcher
不同的方式编写我们的:
data() {
return {
count: {
number: 1,
type: 'number'
}
},
watch: {
count: {
handler(data) {
console.log(data);
},
deep: true
}
}
}
现在,只要其中的任何属性count
发生变化,count
观察者就会触发。这console.log(data)
一次,整个count
对象将被控制台记录,即{ number: 1, type: 'number' }
.
这比在属性中定位特定属性要容易得多,但成本很高。由于 Vue 每次都必须遍历每个属性,这可能会导致非常大的对象出现严重的性能问题。因此,仅当您有一个已知的小尺寸对象时才使用它。对于其他情况,请坚持针对特定属性,例如count.number
.