vue3+ts+cli:在setup中使用watch

watch(obj,callback,config)

watch方法接收三个参数:
obj:要监听的对象;
callback:监听事件的处理,接收newValue和oldValue两个参数;
config:监听事件的配置项。

实例

	import {
    
    ref,reactive,watch,watchEffect} from 'vue';
	setup(){
    
    
		let num = ref(0);
    	let str = ref('你好啊!');
    	let animal = ref({
    
    
    		name:'dog',
    		age:100,
    		jog:{
    
    
    			jb1:{
    
    
					type:'call'
				}
    		}
		})
		let person = reactive({
    
    
		      name:'张三',
		      age:100,
		      job:{
    
    
		          jb1:{
    
    
		              type:'web'
		          }
		      }
		})
		
		//监听ref定义的值
		watch(num,(newValue,oldValue)=>{
    
    
			console.log(newValue);  //1
			console.log(oldValue);  //0
		},{
    
    
			immediate:false, //默认为false,是否在页面加载后先触发一次回调
			deep:true, //默认为false,是否开启深度监视
		})
		//改变num的值
		num.value = 1;
		
		//监听reactive定义的对象中的某个值,值以函数返回值的形式传入
		watch(()=>person.age,(newValue,oldValue)=>{
    
    })
		
		return {
    
    num,str,person};
	}

watch在监听不同数量的元素时有不同写法
监听多个元素时:

	/*
	监听的元素以数组形式传入,同时newValue和oldValue的值也以数组形式与之一一对应
	监听的任一元素改变时都会调用回调
	*/
	//监听ref定义的值
	watch([num,str],(newValue,oldValue)=>{
    
    
		//num或str的值变化时都会触发回调
		console.log(newValue);  //[1, '你好啊!']
		console.log(oldValue); //[0, '你好啊!']
	})
	num.value = 1;  
	
	//监听reactive定义的对象中的值,值以函数返回值的形式传入
	watch([()=>person.age,()=>person.name],(newValue,oldValue)=>{
    
    })

当监听ref定义的对象类型时:

	/*
		内部借助reactive生成proxy对象
		此时变量的value属性就相当于直接借助reactive生成的对象
		因此需要监听变量的value属性
	*/
	watch(animal.value,()=>{
    
    })

当监听reactive定义的对象类型时:

	/*
		此文发布时,watch监听reactive定义对象存在的一些bug:
			1.newValue和oldValue的值是相同的,都是newValue;
			2.deep配置无效,只能开启深度监视,无法关闭;
	*/
	watch(person,(newValue,oldValue)=>{
    
    
		console.log(newValue);
		console.log(oldValue);
	},{
    
    
		deep:false
	})
	//改变name值,返回的newValue和oldValue的值都是newValue
	person.name = '李四'; 	//newValue/oldValue:{name: '李四', age: 100, job: {…}}

	//改变jb1.type,触发了回调 
	person.job.jb1.type = 'work'; //此时配置项deep为false,但在jb1.type改变时依然触发了watch的回调

监听reactive定义的对象中的某个值时

	//当监听的值为具体值时
	watch(()=>person.job.jb1.type,(newValue,oldValue)=>{
    
    
		console.log(newValue);  //web
		console.log(oldValue);  //ios
	}) 
	person.job.jb1.type = 'ios';  //此时newValue和oldValue值显示正常
	
	//当监听的值为对象时
	watch(()=>person.job,(newValue,oldValue)=>{
    
    
		console.log(newValue); 
		console.log(oldValue); 
	},{
    
    
		deep:false
	})
	//此时修改对象中的属性不会触发回调,也就是说无法深度监测,需要在配置项中修改deep的值为true
	//当修改deep值为true时,回调会被触发,但是此时newValue和oldValue的值又一样了
	person.job.jb1.type = 'work'; 

总结

当监听由ref定义的属性时:
1.当监听的数据是基本类型时,不需要加.value;
2.当监听的数据是对象类型时,需要加.value;此时监听的RefImpl对象,其中的value值是借助reactive生成的proxy对象,如果不加.value时,此时只有当对象被整体替换,即指针发生变化时才会触发监听;当然也可以通过配置deep属性来开启深度监听;

当监听由reactive定义的属性时:
1.当监视的是由reactive直接监听的属性时,deep会强制开启;
2.当监视的是reactive定义的响应式中某个属性时,deep属性有效,且默认false;

猜你喜欢

转载自blog.csdn.net/weixin_44439874/article/details/121901132