如何观察 Vue 中的嵌套变化

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.