X

XiaoSong

V1

2023/02/08阅读:22主题:默认主题

Vue3使用技巧-监听器2

深层监听器

watch的第一个参数直接传入响应式对象时,默认开启深层监听,不管对象中嵌套的第几个对象的第几个属性,只要发生改变就会触发watch的回调函数:

const obj = reactive({ 
    goodsClass: { 
        name'phone',
        price: { 
            phone1'1499',
            phone2'1599'
        }
    }
})

watch(obj, (newValue, oldValue) => { 
  // 在嵌套的属性变更时触发,注意:`newValue` 此处和 `oldValue` 是相等的
  // 因为它们是同一个对象!
    console.log(newValue === oldValue) // true
})

相比之下,使用getter函数,只用当整个对象都改变了才会触发watch的回调函数

// obj.goodsClass整个对象的值被改变了才会触发,如果只改里面的一个属性就不会触发回调
watch(() => obj.goodsClass, (newValue, oldValue) => { 
    console.log(newValue, oldValue) 
})

例如:

<!-- 只绑定的name属性,当name改变时不会触发回调函数 -->
<input
v-model.lazy="obj.goodsClass.name"
placeholder="输入name"
/>

<!-- 只绑定的整个obj.className对象,当整个对象改变时会触发回调函数 -->
<input
v-model.lazy="obj.goodsClass"
placeholder="输入name"
/>

也可以给watch加上{ deep: true },强制开启深度监听

watch(() => obj.goodsClass, (newValue, oldValue) => { 
    console.log(newValue===oldValue) // true
},
deeptrue }
)

NOTE: 一般不要使用深度监听,因为要遍历整个对象,如果数据比较复杂会严重影响性能

即时回调的侦听器

watch中加上{immediate: true},创建监听器时立即执行一遍回调函数,当数据改变后在执行一次。以下案例中使用定时器模拟异步获取数据。

const init = reactive({ 
    name'vuex',
    version3
})

watch(init, (newValue) => { 
    // 会输出两次,一次是初始的数据,一次是改变后的
    console.log(newValue)
}, {immediatetrue})

const getData = () => { 
    return new Promise((resolve, reject) => { 
        setTimeout(() => { 
            init.version = 4
        }, 2000)
    })
}

onMounted(async () => { 
    await getData()
})

分类:

前端

标签:

Vue.js

作者介绍

X
XiaoSong
V1