今天在写vue项目时发现了几个问题,困扰了我,花时间研究了一下,做个笔记:
1.组件状态没有定义成响应式的数据,更改时不会更新视图,
什么是响应式数据?怎么定义响应式数据?其实很简单,定义在data里面的数据就是响应式的,更新这里面的数据时,应用这个数据的地方会重新渲染更新视图,达到响应式数据的目的。这是因为vue在初始化的时候initData()时对data里面的数据添加了getter和setter,getter会收集应用这个数据的dep(依赖),setter时会通知dep更新,这里就不展开说明了,以后研究明白了再说。
2.对象增加没有定义成响应式数据的时候不会更新视图,
这个原因很简单,对象增加新的没有定义多的字段时,这个字段没有经过initData()初始化,没有getter和setter属性,所以不是响应式数据。
3.父组件通过props传递对象数据到子组件时:增加没有定义成响应式属性时父组件不更新视图导致子组件也不会更新props,导致子组件拿不到最新props、也不会更新视图,
其实这个和2中的原因类似,增加非响应式字段,父组件不会更新视图,导致子组件也不会更新,自然就获取不到最新的props。
4.通常情况下vue会收集setData在合适的时机统一更新视图,但使用了await关键字的异步方法的then()里面的setData会单独更新视图,不与外面的setData同时更新
这个暂时还不知道原因,后面再更新
解决方法:
①.通常可以使用$set()解决对象新增未定义的属性,
$set()是vue公开的添加响应式属性的api,有三个参数
(1:要修改的对象,2:这个对象要修改或增加的字段名,3:这个字段的值)
例:$set(obj,key,value)
②.使用ES6的解构赋值obj={...obj,newKey:value},其实这个能触发视图更新的原因是因为修改了obj,obj定义在data中,始终是响应式数据,所以能触发重新渲染。
---------------------------------------------------------------------------------------------------------------------------------
今天发现了一个小程序中vue的一个差异,当在父组件绑定一个obj数据时,通过props传递给子组件,通过方法修改这个obj:
handleModify(){
this.obj = {a:1,b:2}
}
重复触发这个方法,父组件中每次都会触发obj的watch和update生命周期,但是子组件只有第一次会触发obj的watch,update生命周期一直不触发,
但是在web端是每次都会触发父组件和子组件中obj的watch和update生命周期??这就很神奇!!