【Vue3基础】watch函数

392 阅读3分钟

先定义三个数据:counter、personOne、personTwo

部分html: <button @click="shu++">counter</button>

const counter = ref(0)
const personOne = ref({ // person是个proxy对象,而person.age是一个具体的值:12
    age: 12,
    name: 'lwx',
    msg: { // person.msg是个proxy对象
        form: '湖北',
        station: '江汉'
    }
})
const personTwo = reactive({ // person是个proxy对象,而person.age是一个具体的值:12
    age: 12,
    name: 'lwx',
    msg: { // person.msg是个proxy对象
        form: '湖北',
        station: '江汉'
    }
})
watch(() => personOne.value.msg, (newVal, oldVal) => { 
    console.log(newVal, oldVal, '*****personOne.msg')

}, { deep: true })

watch(() => counter.value, (newVal, oldVal) => { 
    console.log('改变了', newVal, oldVal)
}, { deep: true })

const myMsg = ref({ //深度嵌套
    a: 1,
    b: {
        c: {
            d: 'd'
        }
    }
})
watch(
    [
        () => p.num,
        () => p.setNum,
        () => myMsg.value.b.c.d,
        () => myMsg2.b
    ],
    // (newVal, oldVal) => {
    //     console.log('num或setNum或text改变了,', newVal, oldVal)两种写法,① 数组
    // },
    ([newVal1, newVal2, newVal3, newVal4], [oldVal1, oldVal2, oldVal3, oldVal4]) => {
        // console.log('num或setNum或text改变了,', newVal, oldVal) // ② 单个的数值,就是解构赋值的写法
        console.log('num或setNum或text改变了,', newVal1, newVal2, newVal3, newVal4, '========', oldVal1, oldVal2, oldVal3, oldVal4)
    },
    { immediate: true, deep: true } // 监听的是外层的属性,而内层的数据改变了,应该深度监视
    )
    
watch(counter, (newVal, oldVal) => { //与普通方法的不同是:可以监听异步的操作!
    setTimeout(() => {
        counter.value = 0
        console.log(newVal, oldVal)
    }, 3000)
})

ref 对象(可以是基本数据类型;也可以是复杂数据类型,复杂数据类型里面可以包含基本类型)

    // personOne 加上了 deep: true 只会得到新值newVal  oldVal一样,且不知道哪个值变了 X
    // personOne.value 只会得到新值newVal  oldVal一样,且不知道哪个值变了  X 
    // () => ## personOne.value.age √
    // personOne.value.age 加上了 deep: true也监听不到personOne.value.age 的变化 X
    // () => personOne.value.msg.form  加上了 deep: true 
    // () => personOne.value.msg.form  不加上 deep: true 
    // personOne.value.msg.form 加上了 deep: true X
    // personOne.value.msg.form 不加上了 deep: true X
    // () => personOne.value.msg.form X

1、ref对象中-基本数据类型

 ①推荐使用(即() => counter.value) 
 ②counter不加.value( 如果加了就相当于取出了0这个具体的值,且基本数据类型最好不加deep: true,虽然某些情况不加也是对的) ;

2、ref对象中-复杂数据类型中的基本数据类型

() => personOne.value.age 和 deep:true即可 

3、ref对象中-复杂数据类型中的复杂数据类型,可以监听一个复杂数据类型的变化,但是不能监听里面具体的属性变化

总结:

①在监听ref对象时,具体的基本数据类型,要加上箭头函数监听,复杂数据类型可以不加箭头函数;在监听ref复杂数据对象时,当内层数据改变了,而监听的是外层数据,只会监听到改变且不会监听到具体是内层哪个数据变了(newVal 和 oldVal一样);

②deep: true,在复杂数据类型中加上,基本数据类型最好不加,虽然某些情况加了也是对的 (ref中嵌套的proxy对象才能deep: true)

reacitve 对象(只有复杂数据类型,复杂数据类型里面可以包含基本类型)

// ()=> personTwo X
// personTwo 只会得到新值newVal 和 oldVal一样,且不知道哪个值变了 X 
// personTwo.age  X
// ()=> personTwo.age  √
// ()=> personTwo.msg.form  √
// () => personTwo.msg 加上了 deep: true也监听不到personTwo.msg.form 的变化  X

总结:

①在监听reactive对象时具体的基本数据类型,要加上箭头函数监听,复杂数据类型可以不加箭头函数;在监听reactive复杂数据对象时,当内层数据改变了,而监听的是外层数据,只会监听到改变且不会监听到具体是内层哪个数据变了(新值newVal 和 oldVal一样);

②deep: true是无效的,因为reactive集成的proxy对象默认是深度监听(deep: true针对的是ref的复杂类型数据)

上述是个人随笔,可能有不足之处,仅供参考