Vue watch() 与 watchEffect()简介

watch()

函数原型:

@原型:watch( param, callback, options)
@params:
    param:   [必需] 被监听对象
    callback: [必需] 被监听对象发生变化时执行回调
        callback: function(newValue, oldValue) {
            // newValue 变化后的值
            // oldValue 变化前的值
        }

    options:  [可选] 监听参数
        options: {
          deep: true,  //[true| false] 值true表示深度监听
          immediate: false, //[true|false] 默认wath是懒执行,设置值为true表示初始化时就执行一次,使其具有和watchEffect() 一样的特性
          flush: 'pre'  // ['pre|post|sync] 控制回调时间
                        // pre: 默认值。回调应该在渲染前被调用
                        // post: 将回调推迟到渲染之后的
                        // sync: 一旦值发生了变化,回调将被同步调用
        }
@return: [Fun] 执行该函数用于中止监听

 

监听ref对象

<script setup>
    import {
        ref,        
        watch       
    } from 'vue'

    const studentNumber = ref(0)  

    watch(
        studentNumber,
        (newV, oldV) => {
            console.log(newV);
        }, 
        {
            immediate: true //使监听初始化时就执行一次
     })
</script>

 

监听函数、表达式

<script setup>
    import {
        ref,      
        watch    
    } from 'vue'

    const studentNumber = ref(10)

    watch(
        // 注意:第一个参数是一个函数。它监听函数的返回值
        () => studentNumber.value * 5, 
        (newV, oldV) => {
            // 这里的newV值是函数返回值的结果
            console.log('总班费:' + newV + '元');
        })
</script>

 

监听reactive对象

<script setup>
    import {
        reactive,
        watch
    } from 'vue'

    const student = reactive({
        name: '张三',
        age: 15,
        contact: {
            phone: '18714896998',
            qq: '103422412',
            email: 'wm218@qq.com'
        }
    })

    watch(student, (newV, oldV) => {
        console.log(newV);
    })
</script>

 

监听reactive对象的某个属性

不能直接监听student.name,因为它返回是的一个值,而不是对象。所以这里采用监听函数的方式来实现

<script setup>
    import {
        reactive,
        watch
    } from 'vue'

    const student = reactive({
        name: '张三',
        age: 15,
        contact: {
            phone: '18714896998',
            qq: '103422412',
            email: 'wm218@qq.com'
        }
    })

    watch(
()
=> student.name,
(newV, oldV) => { console.log(newV); }) </script>

 

监听计算属性

<script setup>
    import {
        ref,       
        watch,       
        computed
    } from 'vue'

    const studentNumber = ref(0)

    // 定义计算属性
    const getMoney = computed(() => studentNumber.value * 5)
    
    watch(getMoney, (newV, oldV) => {
        console.log('总班费:' + newV + '元');
    })
</script>

 

监听多个数据

<script setup>
    import {
        ref,
        reactive,
        watch

    } from 'vue'

    const studentNumber = ref(0)
    const student = reactive({
        name: '张三',
        age: 15,
        contact: {
            phone: '18714896998',
            qq: '103422412',
            email: 'wm218@qq.com'
        }
    })


    watch(
         //将多个数据以数组元素代入
         [studentNumber, () => student.name],

        // 注意这里是将新值放在一个数组,旧值放在第二个数组
        // [新值1,新值2], [旧值1,旧值2]
        ([studentNumberNewV, nameNewV], [studentNumberOldV, nameOldV]) => {
            console.log(studentNumberNewV);
            console.log(studentNumberOldV);
            console.log(nameNewV + '===' + nameOldV);
    })
</script>

 

停止监听

<script setup>
    import {
        ref,       
        watch      
    } from 'vue'

    const studentNumber = ref(0)   

    var stopWatch = watch(
        studentNumber,
        (newV, oldV) => {
            console.log(newV);
        })

    // 执行 stopWatch() 可以停止监听
</script>

 

 

 

watchEffect()

watchEffect()特性:

1、watchEffect()会监听函数内所有出现的对象,无需特别指定对象。

//本例中函数使用了studentNumber,则其自动被认为是侦听对象,当其值发生变化时,自动触发
watchEffect(()=>{
    console.log(studentNumber.value)
})

 

2、不论watchEffect()内是否设置了侦听对象,初始化时它都会执行一次,比如以下代码:

// 虽然内部出现侦听对象,但也会执行
watchEffect(()=>{
    console.log(222); // 初始化时这里会执行
})

 

3、watchEffect()不能侦听异步函数内对象

// 由于studentNumber存在异步函数内,所以它不会被侦听
watchEffect( async ()=>{
     await setTimeout(()=>{
         console.log(studentNumber.value);
     }, 1000)
     console.log(a.value); // 这里a也无法监听,官方的解释:只有在第一个 await 正常工作前访问到的属性才会被追踪。
// 我的理解是:只要前面的侦听失败,后面全部失败
})

 

函数原型:

@原型:watchEffect (callback, options)
@params:
    callback: [必需] 回调函数
    options:  [可选] 监听参数
        options: {
          flush: 'pre',  // ['pre|post|sync] 控制回调时间
                         // pre: 默认值。回调应该在渲染前被调用
                         // post: 将回调推迟到渲染之后的
                         // sync: 一旦值发生了变化,回调将被同步调用
          onTrack(e) {
              debugger
          },
          onTrigger(e) {
               debugger
          }
        }
@return: [Fun] 执行该函数用于中止监听

 

停止监听

const stopWatch = watchEffect(()=>{
    console.log(studentNumber.value)
})

//执行  stopWatch() 可执行监听

 

总结:watch() 与watchEffect()的区别

1、watch() 可以获取值的前后变化。而watchEffect()不可以。

2、watch() 默认属于懒执行.创建侦听时,不执行。而watchEffect()创建侦听时即执行一次。

3、watchEffect()写法自由些,但同时针对异步有点复杂情况。而watch() 执行条件明确。

posted @ 2022-09-15 09:32  1024记忆  阅读(558)  评论(0编辑  收藏  举报