• 技术文章 >web前端 >Vue.js

    一文详解Vue中watch和watchEffect的区别

    藏色散人藏色散人2022-08-09 15:20:39转载453

    前言

    watch函数与watchEffect函数都是监听器,在写法和用法上有一定区别,是同一功能的两种不同形态,底层都是一样的。【相关推荐:vue.js视频教程

    watch和watchEffect的对比

    watch

    watchEffect

    深度解析watch函数

    watch函数有两个小坑:

    具体的watch函数的用法在下面代码中都有所体现,注释详细

    <template>
        <div>
            <h2>当前求和为:{{sum}}</h2>
            <button @click="sum++">点我+1</button>
            <hr>
            <h2>当前的信息为:{{msg}} </h2>
            <!-- 点击button拼接! -->
            <button @click="msg+='!'">修改数据</button>
            <hr>
            <h2>姓名:{{person.name}}</h2>
            <h2>年龄:{{person.age}}</h2>
            <h2>薪资:{{person.job.j1.salary}}</h2>
            <button @click="person.name+='~'"> 修改姓名</button>
            <button @click="person.age++"> 增长年龄</button>
            <button @click="person.job.j1.salary++"> 增长薪资</button>
        </div>
    </template>
    
    <script>
    import {ref,reactive,watch,watchEffect} from 'vue'
    export default {
       name:'demo',
       setup(){
           //数据
           let sum = ref(0)
           let msg = ref('hello')
           let person = reactive({
               name:'zhangsan',
               age:'18',
               job:{
                   j1:{
                       salary:20
                   }
               }
           })
           //监视(三个参数,第一个是监视的对象,第二个是监视的回调函数,第三个是监视的配置)
    
           //情况一:监视ref所定义的一个响应式数据
           watch(sum,(newValue,oldValue)=>{
               console.log('sum的值变化了',newValue,oldValue)
           },{immediate:true,deep:true})
           //immediate的值为true时表示非惰性的立即执行的(默认情况下是false)
           //deep深层次触发(此处设置deep无意义)
    
           //情况二:监视ref所定义的多个响应式数据,写成数组的形式
    
           watch([sum,msg],(newValue,oldValue)=>{
               console.log('sum或者msg变了',newValue,oldValue)
           })
    
           //情况三:监视reactive所定义的响应式数据
                    //若监视的是reactive定义的响应式数据,则无法正确获得oldValue
                    //若监视的是reactive定义的响应式数据,则watch会强制开启深度监视
    
            //我们发现改变person的任意一个属性都会被监视到
            watch(person,(newValue,oldValue)=>{
                console.log('person改变了',newValue,oldValue)
            }) 
            
            //我们尝试设置deep:false,关闭深度监听(目的:改变job的值不会被watch监听到)
            //但是我们发现deep:false并没有生效,原因是此时watch监视的是reactive定义的响应式对象,默认强制开启了深度监听
            watch(person,(newValue,oldValue)=>{
                console.log('person改变了',newValue,oldValue)
            },{deep:false}) 
            
    
    
          //情况四:监视reactive所定义的响应式数据中的某个属性
           watch(()=>person.name,(newValue,oldValue)=>{
                console.log('person的job改变了',newValue,oldValue)
            })
             watch(()=>person.age,(newValue,oldValue)=>{
                console.log('person的job改变了',newValue,oldValue)
            })
            watch(()=>person.job,(newValue,oldValue)=>{
                console.log('person的job改变了',newValue,oldValue)
            })
            //从上边我们发现改变name,age都会触发监听,但是改变job不会
            //这是因为name和age属性的值只是一个简单的基本类型数据,
            //而job属性的值是一个对象,比较深,想要监视到,就要开启深度监视,程序如下:
            watch(()=>person.job,(newValue,oldValue)=>{
                console.log('person的job改变了',newValue,oldValue)
            },{deep:true})//此时job改变,会被监视到,此处的deep配置生效
            //需要和情况三进行区分,此处watch监视的是reactive所定义的对象中的某个属性,而情况三watch监视的是reactive所定义的对象
    
          //情况五:监视reactive所定义的响应式数据中的某些属性,写成数组的形式
            watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
                console.log('person的name或age改变了',newValue,oldValue)
            })
    
           //返回一个对象(常用)
           return{
               sum,
               msg,
               person
           }
       }
    }
    </script>

    watch取消监听

    const stop1 = watch(
      [() => nameObj.name, () => nameObj.name],
      ([curName, curEng], [prevName, curEng]) => {
        console.log(curName, curEng, "----", prevName, curEng);
        setTimeout(() => {
          stop();
        }, 5000);
      });

    深度解析watchEffect函数

    函数用法如下代码所示,注释详细:

    <template>
        <div>
            <h2>当前求和为:{{sum}}</h2>
            <button @click="sum++">点我+1</button>
            <hr>
            <h2>当前的信息为:{{msg}} </h2>
            <!-- 点击button拼接! -->
            <button @click="msg+='!'">修改数据</button>
            <hr>
            <h2>姓名:{{person.name}}</h2>
            <h2>年龄:{{person.age}}</h2>
            <h2>薪资:{{person.job.j1.salary}}</h2>
            <button @click="person.name+='~'"> 修改姓名</button>
            <button @click="person.age++"> 增长年龄</button>
            <button @click="person.job.j1.salary++"> 增长薪资</button>
        </div>
    </template>
    
    <script>
    import {ref,reactive,watch,watchEffect} from 'vue'
    export default {
       name:'demo',
       setup(){
           //数据
           let sum = ref(0)
           let msg = ref('hello')
           let person = reactive({
               name:'zhangsan',
               age:'18',
               job:{
                   j1:{
                       salary:20
                   }
               }
           })
    //watchEffect函数内部所指定的回调中用到的数据只要发生变化,就会重新执行回调
    //只有一个参数,就是回调
        watchEffect(()=>{
            const x1 = sum.value//因为sum是ref定义的响应式数据,需要使用.value调用
            const x2 = person.age
            console.log('watchEffect配置的回调执行了')
        })
               return{
               sum,
               msg,
               person
           }
       }
    }
    </script>

    watchEffect取消监听

    const stop = watchEffect(() => {
      console.log(nameObj.name);
      setTimeout(() => {
        stop();
      }, 5000);});

    watchEffect与computed

    watchEffect与computed有点像:

    举例:

    <template>
        <div>
            <h2>当前求和为:{{sum}}</h2>
            <button @click="sum++">点我+1</button>
            <hr>
            <h2>当前的信息为:{{msg}} </h2>
            <!-- 点击button拼接! -->
            <button @click="msg+='!'">修改数据</button>
            <hr>
            <h2>姓名:{{person.name}}</h2>
            <h2>年龄:{{person.age}}</h2>
            <h2>薪资:{{person.job.j1.salary}}</h2>
            <button @click="person.name+='~'"> 修改姓名</button>
            <button @click="person.age++"> 增长年龄</button>
            <button @click="person.job.j1.salary++"> 增长薪资</button>
        </div>
    </template>
    
    <script>
    import {ref,reactive,watch,watchEffect, computed} from 'vue'
    export default {
       name:'demo',
       setup(){
           //数据
           let sum = ref(0)
           let msg = ref('hello')
           let person = reactive({
               name:'zhangsan',
               age:'18',
               job:{
                   j1:{
                       salary:20
                   }
               }
           })
           let person1 = reactive({
               firstName:'张',
               lastName:'三'
           })
           //computed
           //计算属性——简写(没有考虑计算属性被修改的情况)
           person1.fullName = computed(()=>{
               //必须含有返回值
               return person1.firstName+'-'+person1.lastName
           })
    
           //计算属性——完整写法(考虑读和写)
           person1.fullName = computed({
               //必须含有返回值
               get(){
                   return person1.firstName+'-'+person1.lastName
               },
               set(value){
                   const nameArr = value.split('-')
                   person1.firstName = nameArr[0]
                   person1.lastName = nameArr[1]
               }
           })
           //watchEffect
            //可以不写给返回值
            watchEffect(()=>{
                const x1 = sum.value//因为sum是ref定义的响应式数据,需要使用.value调用
                const x2 = person.age
                console.log('watchEffect配置的回调执行了')
            })
             return{
               sum,
               msg,
               person,
               person1
           }
       }
    }
    </script>

    以上就是一文详解Vue中watch和watchEffect的区别的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:csdn,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    快捷开发Web应用及小程序:点击使用

    支持亿级表,高并发,自动生成可视化后台。

    专题推荐:watchEffect watch Vue
    上一篇:深入解析Vue的计算属性API(computed) 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 深入了解Vue中的Watcher和Scheduler• 认识Vue中的computed 和 watch,聊聊它们的区别• 一文了解Vue3中的watchEffect,聊聊其应用场景!• 浅析Vue中的watch侦听器、计算属性、Vue-cli和组件
    1/1

    PHP中文网