记录一下VUE3.0的watch

161 阅读1分钟
let data = reactive({
        name: '張三',
        gender: '男'
})
watch(data, (newVal, oldVal) => { // 可以直接監聽reactive的數據,正確

})
watch(data.name, (newVal, oldVal) => { // 如果是想監聽對象裡面的屬性,這樣寫是不行的,錯誤

})
watch(() => data.name, (newVal, oldVal) => { // 必須這樣寫,因為監聽器需要監聽一個getter函數,正確

})
watch([data.name, data.gender], (newVal, oldVal) => { // 監聽多個,還是那句話,要用函數才可以,錯誤

})
watch(() => [data.name, data.gender], (newVal, oldVal) => { // 監聽多個,正確

})

监听父组件传值就更简单了

props: {
    aaa: {
        type: String,
        default: ''
    }
},
setup(props, content) {
    watch(()=>props, (newValue) => { // 監聽父組件傳值
        console.log(newValue)
    })
}

另外还有两个属性,记录一下:deep和immediate,deep用于深度监听,如果你的data是一个proxy,然后你直接修改了data中的某个属性的值,此时监听是无效的,需要加deep;immediate用于立即执行,比方说你想进入页面立马执行watch的话,就加immediate

PS: 补充,如果监听的是引用类型,那么不管值是否发生了改变,都会触发watch。解决方案:1、要么不要选择监听引用类型,改为基本类型;2、要么就是在监听的事件里面再做一些逻辑处理,像下面这样。之前没做第二层逻辑判断就一直很懵逼,明明打印出新值和旧值都是一样的,为毛onGetData()触发了两次

// watch监听-------------------------------------------------------
    watch(()=> store.state.csWorkPanelsAccount, (newVal, oldVal) => {
        if (newVal) {
            // csWorkPanelsAccount是引用类型,新值和旧值即便相同也会触发watch,所以这里还要再做一层逻辑判断
            if (!oldVal || (newVal.account != oldVal.account)) {
                data.account = store.state.csWorkPanelsAccount.account
                onGetData()
            }
        } else {
            onInitData()
        }
    }, {deep: true})