computed和watch、watchEffect


前言

computed 计算属性 : computed储存需要处理的数据值,依赖其它的属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,再获取 computed 的值时才会重新计算。

watch监听器:用于监听数据变化,当监听的数据发生变化时执行回调进行后续操作。监听的数据来源有三部分:props、data、computed内的数据;watch提供两个参数(newValue,oldValue),新值,旧值。


一、computed计算属性:

setup(){
   let p = reactive({
       startName:'李',
       endName:'增'
    })
   p.fullName = computed({
       get(){
           return p.startName + '-' + p.endName
        }
       set(val){
           let res = val.split('-')
           p.startName = res[0];
           p.endName = res[1];
        }
    })
}

如上代码所示,startName和endName的值发生改变时,fullName的值根据startName和endName重新进行计算。 

<template>
    <p>total:{
   
   {arrTotal}}</p>
</template>

<script>
    export default{
        data(){
            return{
                arr:[1,2,3,4]
            }
        },
        mounted(){
            setTimeout(()=>{
                this.arr[0] =5;
            },2000)
        },
        computed:{
            arrTotal:function(){
                let total = 0;
                this.arr.map(item=>{
                    total += item;
                })
                return total;
            }
        }
    }
</script>

computed特点: 

  •  支持缓存,当依赖的数据发生改变,才会重新进行计算;
  • 不支持异步,如果computed中有异步操作,无法监听数据的变化;
  • 计算属性是基于它们的响应式依赖进行缓存的,当依赖的响应式数据发生改变时,计算属性才会改变;
  • 一个值依赖多个属性(多对一)

二、watch监听器:

setup(){
    let num = ref(20);
    let sum = computed({
        get(){
            return num.value + 20;
        }
    })
    let message = ref('watch监听');
    watch(sum,(newValue,oldValue) => {
        console.log('sum改变了',newValue,oldValue);
    })
    watch([sum,message],(newValue,oldValue)=>{
        console.log('sum或者message改变了',newValue,oldValue);
        //返回为两个数组:[sum新值,message新值]  [sum旧值,message旧值]
    })
}

如上代码所示,当watch监测到sum或者message发生改变,便会触发后面的操作,log内容。

data(){
    return{
        user:{
            name:'小小'
        },
        num:20
    }
},
mounted(){
    setTimeout(()=>{
        this.user.name = 'alim';
        this.num = 40;
    },2000)
},
watch:{
    user:{
        handler(val){
            console.log('user发生改变',val);
            //user发生改变 Proxy {name: "alim"}
        },deep:true
    },
    num:function(newValue,oldValue){
        console.log('num改变了',newValue,oldValue);
    }
}

watch特点: 

  •  watch支持异步监听;
  • 不支持缓存,数据变化时,它就会触发相应的操作;
  • 监听的函数接收两个参数:第一个是最新的值,第二个是变化之前的值;
  • 如果一个值变化后会引起一系列操作,或者一个值变化会引起一系列值的变化(一对多),用watch更加方便一些;
  • 监听data或者props传来的数据,发生变化时会触发相应操作。有两个参数:

         immediate:立即触发回调函数。

        deep:深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象内容发生变化。

 在vue3.0中有一些特殊的地方:

vue3.x监听 reactive 所定义的一个响应式数据

1.注意:此处无法正确获取oldValue
2.注意:强制开启了深度监测,(deep配置无效)

watch(person,(newValue,oldValue)=>{
   console.log('person变化','new:',newValue,'old',oldValue)
},{immediate:true,deep:true})  //此时deep设置无效

 vue3.x监听 reactive 所定义的一个响应式数据中的某个属性,需要写到函数里面

watch(()=>person.name,(newValue,oldValue)=>{
    console.log(newValue,oldValue,'name')
},{immediate:true,deep:true})

() => person.name 

vue3.x监听 reactive 所定义的一个响应式数据中的某些属性(需要用数组包裹,在写到函数里面) 

watch([()=>person.name,()=>person.age], (newVal, oldVal) => {
      console.log('person.name或.age值变化了', newVal, oldVal);
});

 三、watchEffect函数

 watch 监听器:既要指明监听的属性,也要指明监听的回调

 watchEffect:  不用指明监视哪个属性,监听的回调中用到哪个属性,那就监听哪个属性

watchEffect有点像computed:

  • 但是computed更注重的是计算出来的值(回调函数的返回值),所以必须要写返回值
  • 而watch更注重的是过程(回调函数的函数体),所以不用写返回值
watchEffect(() => {  
      console.log('回调执行了',user.name);
});
//每次修改msg都会执行

 四、使用场景

computed:多个数据影响一个(多对一)。当需要依赖于其他属性进行数值计算,应该使用computed,可以利用computed的缓存特点,避免每次都会重新计算。

watch:一个数据发生变化,执行相应操作会影响多个数据(一对多) 。需要再数据变化时执行异步或者执行较为复杂的操作时,使用watch,例如:使用watch允许执行异步操作,限制执行该操作的频率,并在得到最终结果前,设置中间状态。

猜你喜欢

转载自blog.csdn.net/weixin_42464106/article/details/125636669
今日推荐