当前位置: 首页 > Web前端 > HTML

Vue的computed和watch详情综合分析

时间:2023-04-02 13:12:07 HTML

1.computed1.1定义是一个computed属性,类似过滤器,处理绑定到view的数据1.2getusagedata:{firstName:'Foo',lastName:'bar'},computed:{fullName:function(){returnthis.firstName+''+this.lastName}}data中不能定义fullName,定义了会报错如下图,因为对应的computed作为calculation属性定义了fullName并将对应的结果返回给这个变量。变量不能重复定义和赋值1.3get和setusagedata:{firstName:'Foo',lastName:'Bar'},computed:{fullName:{get(){//当前属性值时执行回调函数需要读取,根据相关数据计算返回当前属性的值returnthis.firstName+''+this.lastName},set(val){//监听当前属性值的变化,当属性值变化时,更新相关属性数据//val为fullName的最新属性值console.log(val)constnames=val.split('');console.log(names)this.firstName=names[0];this.lastName=名字[1];}}}2.watch2.1将watch定义为观察到的动作2.2示例数据:{firstName:'Foo',lastName:'Bar',fullName:'FooBar'},watch:{firstName:function(val){this.fullName=val+''+this.lastName},lastName:function(val){this.fullName=this.firstName+''+val}}上面是监听firstName和lastName的变化,但是只有简单数据类型2.2监听简单数据类型data(){return{'first':2}},watch:{first(){console.log(this.first)}},2.3复杂数据类型的监听1.复杂数据类型的监听,需要使用深度监控data(){return{'first':{second:0}}},watch:{secondChange:{handler(oldVal,newVal){console.log(oldVal)console.log(newVal)},deep:true}},2.console.log打印结果,发现oldVal的值和newVal是一样的,所以深度监控虽然可以监控到对象的变化,但是无法监控到具体对象中属性的变化。3.oldVal和newVal之所以有相同的值,是因为它们索引的是同一个对象/数组Vue不会保留修改vm.$watch之前的值的副本。深度监控4、深度监控对应的函数名必须是handler,否则没有效果,因为watcher对应的是handler的调用。可以直接使用对象和属性的方法获取属性data(){return{'first':{second:0}}},watch:{first.second:function(newVal,oldVal){console.log(新值、旧值);}},方法二:如果watch要监听对象单个属性的变化,必须使用computed作为中间件转换,因为computed可以得到对应的属性值data(){return{'first':{second:0}}},computed:{secondChange(){returnthis.first.second}},watch:{secondChange(){console.log('secondpropertyvaluechanged')}},3computed和watch的区别3.1Computedfeatures1.是计算出来的值,2.应用:是简化tempalte中{{}}的计算,处理props或$emit的值传递3.可缓存,页面的值重新渲染不改变,计算出来的属性会立即返回3.2watch特性1.是观察的动作,2.应用:监听props,$emit或者这个组件的值来执行异步操作3.没有缓存,页面重新渲染时value没有改变会执行3个props传值3.1常见错误1传入的value想作为局部变量,直接用props:['listShop'],data(){return{}},created(){这个。listShop=30}报错这个错误是为了避免直接修改父组件传入的值,因为会改变父组件的值,贴上官网介绍3.2解决方案1??简单数据类型解决方案:这样就可以了在data变量中重新定义一个,改变指针,但仅限于简单数据类型,因为复杂数据类型堆栈存储指针,props:['listShop'],data(){return{listShopChild:this.listShop}},created(){this.listShopChild=30}这样就可以愉快的更改传入的简单数据类型的数据了!不会有错误,也不会影响到父组件!3.4存在的问题复杂的数据类型在栈中是以指针的形式存储的,所以给一个新的变量赋值也会改变原来的变量值。那么应该怎么办呢?1.可以手动深度克隆一个复杂的数据,循环或者递归可以做数组深度克隆:varx=[1,2,3];vary=[];for(vari=0;i{subs.forEach(sub=>sub())},0)}val=newVal},})}6.1计算实现函数computed(ctx,obj){letkeys=Object.keys(obj)letdataKeys=Object.keys(ctx.data)dataKeys。forEach(dataKey=>{defineReactive(ctx.data,dataKey,ctx.data[dataKey])})letfirstComputedObj=keys.reduce((prev,next)=>{ctx.data.$target=function(){ctx.setData({[next]:obj[next].call(ctx)})}prev[next]=obj[next].call(ctx)ctx.data.$target=nullreturnprev},{})ctx.setData(firstComputedObj)}6.1watch实现函数watch(ctx,obj){Object.keys(obj).forEach(key=>{defineReactive(ctx.data,key,ctx.data[key],function(value){obj[key].call(ctx,value)})})}https://segmentfault.com/a/11...如果您发现本文有误,请指正,如果您觉得这篇文章对您真的有用,请一起交流。谢谢大家阅读!