vue中的 satch VS computed

248 阅读5分钟

vue2

satch

简介

使用场景

如果需要在某个数据变化时做一些事情,使用watch来侦听这个数据变化

优势

使用 watch 选项允许我们执行异步操作(访问一个 API)或高消耗性能的操作,限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态,而这些都是计算属性无法做到的。

基本使用

当被监视的属性变化时, 回调函数自动调用, 进行相关操作.

监视的属性必须存在,才能进行监视!!

监视的两种写法:

(1).new Vue时传入watch配置

watch:{
    isHot:{
            immediate:true, //初始化时让handler调用一下。
            
            //handler什么时候调用?当isHot发生改变时。
            handler(newValue,oldValue){
                    console.log('isHot被修改了',newValue,oldValue)
            }
    }
} 

(2).通过vm.$watch监视

vm.$watch('isHot',{
        immediate:true, //初始化时让handler调用一下
        
        //handler什么时候调用?当isHot发生改变时。
        handler(newValue,oldValue){
                console.log('isHot被修改了',newValue,oldValue)
        }
})

深度监视

- Vue中的watch默认不监测对象内部值的改变(一层)。

- 配置deep:true可以监测对象内部值改变(多层)。

监视多级结构某个属性的变化

'numbers.a':{
        handler(){
                console.log('a被改变了')
        }
}

监视多级结构所有属性的变化

numbers:{
        deep:true,//开启深度监视,即监视对象
        handler(){
                console.log('numbers改变了')
        }
}

简写方式

//内部函数式
watch:{
    isHot(newValue,oldValue){
            console.log('isHot被修改了',newValue,oldValue,this)
    }
}
//外部函数式
vm.$watch('isHot',(newValue,oldValue)=>{
        console.log('isHot被修改了',newValue,oldValue,this)
}) 

注意

  1. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!

  2. 使用watch时根据数据的具体结构,决定是否采用深度监视。

computed

简介

使用场景

如果一个数据依赖于其他数据时使用计算属性

原理

底层借助了Objcet.defineproperty方法提供的getter和setter。

优势

内部有缓存机制,可复用,高效清新。

基本使用

//例:
computed:{
	fullName:{
		//get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
		//get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
		get(){
			// console.log(this) //此处的this是vm
			return this.firstName + '-' + this.lastName
		},
		//set什么时候调用? 当fullName被修改时。
		set(value){
                        //通过修改依赖属性来实现对计算属性的修改
			const arr = value.split('-')
			this.firstName = arr[0]
			this.lastName = arr[1]
		}
	}
}

简写方式

//函数式
computed:{
	//可在无修改需求时使用
	fullName(){
		return this.firstName + '-' + this.lastName
	}
}

注意

1.计算属性最终会出现在vue实例上,可直接读取使用。

2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。

satch VS computed

  • computed计算一个新的属性,并将该属性挂载到 Vue 实例上,而watch是监听已经存在且已挂载到 Vue 实例上的数据,所以用watch可以监听computed上属性的变化。

  • computed具有缓存性,只有当依赖变化后,第一次访问computed属性,才会计算新的值,而watch则是当数据发生变化便会调用执行函数

  • computed适用一个数据被多个数据影响,而watch适用一个数据影响多个数据

vue3

计算属性-computed函数

作用

与Vue2.x中computed配置功能一致

写法

import {computed} from 'vue'
    
......
   setup(){
        ......
        //计算属性——简写
        let fullName1 = computed(()=>{
            return Name + '!!!'
        })
        
        //计算属性——完整
        let fullName2 = computed({
            get(){
                return Name + '!!!'
            },
            set(value){
                Name = value
            }
        })
        ......
    }

侦听器-watch函数

作用

与Vue2.x中watch配置功能一致

注意-或许BUG

  1. 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。

  2. 监视reactive定义的响应式数据中某个属性时:deep配置有效。

使用

情况一:监视ref定义的响应式数据

    watch(sum,(newValue,oldValue)=>{
        console.log('sum变化了',newValue,oldValue)
    },{immediate:true})

情况二:监视多个ref定义的响应式数据

    watch([sum,msg],(newValue,oldValue)=>{
        console.log('sum或msg变化了',newValue,oldValue)
    }) 

情况三:监视reactive定义的响应式数据

    /* 
                若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
                若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
    */
    watch(person,(newValue,oldValue)=>{
        console.log('person变化了',newValue,oldValue)
    },{immediate:true,deep:false}) //此处的deep配置不再奏效

情况四:监视reactive定义的响应式数据中的某个属性

    watch(()=>person.job,(newValue,oldValue)=>{
        console.log('person的job变化了',newValue,oldValue)
    },{immediate:true,deep:true}) 

情况五:监视reactive定义的响应式数据中的某些属性

    watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
        console.log('person的job变化了',newValue,oldValue)
    },{immediate:true,deep:true})

特殊情况

    watch(()=>person.job,(newValue,oldValue)=>{
        console.log('person的job变化了',newValue,oldValue)
    },{deep:true}) 
    //监视reactive定义的对象中的某个属性时,deep配置有效

watchEffect函数

理解

  • watch的套路是:既要指明监视的属性,也要指明监视的回调。

  • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到的所有属性

  • watchEffect有点像computed:

    • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
    • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

使用

setup(){
    ......
    watchEffect(()=>{
            const x1 = data.数据1
            const x2 = data.数据2
            console.log('data中的数据1或者数据2改变时触发回调',x1,x2)
    })
    ......
}