Vue监听对象深度监听(打印监听值相同)

    科技2022-08-15  109

    Vue实现对 一般对象 嵌套对象 的监听

    定义一个简单对象 obj 最原始写法 无仍和监听效果

    return {// 定义一个简单对象 **obj** obj: { txt: "oldMsg" }, } watch: {//最原始写法 无仍和监听效果 obj(newVal, oldVal) { console.log(newVal) console.log(oldVal) }, }, created() { this.obj.txt = “newMsg” }

    方法一

    使用:deep:true 为了发现对象内部值的变化,可以在选项参数中指定 deep: true。注意监听数组的变更不需要这么做。

    obj: { //改用deep handler(newVal, oldVal) { console.log(newVal) console.log(oldVal) }, deep: true }

    以上可以实现监听 但是打印的值打印的新旧值相同 稍后给出解决方法

    方法二 (相当于替换对象,使用范围受限)

    this.obj = {txt:'newMsg'}

    对比之前的写法是

    this.obj.txt = “newMsg”

    以上方法相当于是替换对象 ,这种不需要深度监听,也能实现对象的监听 而且打印新旧值不一样,但是使用范围受限,但我们监听对象中变动属性较多,这种方法就不适用了 现在定义一个嵌套对象 objCon

    objCon: { obj1: { msg: "oldMsgCon" } }, watch: { objCon: { handler(newVal, oldVal) { console.log(newVal) console.log(oldVal) }, } }, created() { this.objCon = { obj1: { msg: "newMsgCon" }, } }

    以上也是将对象展开(替换对象),修改某个属性值,能检测到修改,和一般对象一样

    总结以上两种方法

    1,当监听某个具体属性,我们以替换对象的形式,可以监听到变化,不需要深度监听(deep:true),并且打印的新旧值不同,但是使用范围限制,适用于对象单个属性变动

    this.obj = {txt:'newMsg'}

    2,当对象较复杂,并且需要监听属性增删改,可以使用深度监听(deep:true),这个时候可以监听所有类型对象,但是缺点就是监听打印的新旧值相同。 关于这个问题,看官方文档对这一问题的描述,看到最后哪个 ·注意· 没,你注意了嘛

    vm.$watch( expOrFn, callback, [options] ) 参数:

    {string | Function} expOrFn {Function | Object} callback {Object} [options] {boolean} deep {boolean} immediate 返回值:{Function} unwatch

    用法:

    观察 Vue 实例上的一个表达式或者一个函数计算结果的变化。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代。

    注意:在变更 (不是替换) 对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本。

    打印新旧值相同 解决方法(方法三)

    采用computed计算属性监听,间接打印新旧值。因为watch虽然监听到对象(或数组)内部变化,但是由于新旧值同源,导致没有更新。可采用computed计算属性进行对源对象的深拷贝,完成新值更新。如下:

    data() { return { objCon: { obj1: { msg: "oldMsgCon" } }, } }, computed: { newObjCon() { //先用JSON方法在computed属性中对 this.objCon 深拷贝 return JSON.parse(JSON.stringify(this.objCon)) } }, watch: { newObjCon: { //再监听computed属性中以已经深拷贝过的的 this.objCon handler(newVal, oldVal) { console.log(newVal) console.log(oldVal) }, } }, created() { this.objCon.obj1.msg = "newObjCon" }

    这个方法可以解决两者瑕疵,不仅能监听所有复杂对象属性变动,而且监听打印的新旧值还不同,很是方便,希望能帮助到你 此外, Vue动态监听数组可以看这篇文章 Vue动态监听数组

    Processed: 0.010, SQL: 8