源码哥网站的模板,做影视网站用什么源码,建筑企业网站模板免费下载,手机域名做网站中国谁第一家vue2-给data动态添加属性
1. 问题的来源
在VUe2中#xff08;VUE3中使用了proxy#xff0c;及时动态添加也能实现响应式#xff09;#xff0c;如果我们动态给data添加一个属性#xff0c;会发现视图没有同步更新举个例子我们通过v-for遍历data中的一个属性list#xf…vue2-给data动态添加属性
1. 问题的来源
在VUe2中VUE3中使用了proxy及时动态添加也能实现响应式如果我们动态给data添加一个属性会发现视图没有同步更新举个例子我们通过v-for遍历data中的一个属性list生成一系列的div标签然后有一个按钮点击按钮增加一个data的属性list的子项当我们点击按钮时会发现并没有多一个div出来
div v-for(item,index) in list{{item}}/div
button clickaddProperty动态添加属性/button
scriptconst appnew Vue({data(){return{list:{name:tom}}},methods:{addProperty(){this.list.age12//为list动态添加新属性console.log(this.list)//打印添加属性后的list {name:tom , age:12}}}})
/script我们点击按钮发现打印出了新属性但是视图没有得到更新为什么呢得从VUE2的响应式原理说起
2. 原理分析
在VUE2中响应式是通过Object.defineProperty来实现的
const obj{name:tom
}
Object.defineProperty(obj,name,{get(){console.log(get name ${obj[name]})return obj[name]},set(newVal){console.log(set name ${newVal})obj[name]newVal}
})当我们访问name(obj.name)或者设置name(obj.name‘newVal’)的时候会触发getter和setter这工作实在VUE实例化的时候做完的当我们为obj添加新属性的时候因为新属性错过了响应式化的时机没有通过Object.defineProperty设置为响应式数据所以数据改变时无法通知Watcher去更新视图
3. 解决方案
3.1 Vue.set()
既然是因为错过了响应化时机那我们就再把新属性响应化一次就行通过Vue.set向响应式对象中添加一个property并确保这个新property同样是响应式的额。且出发视图更新
function set(target:Arrayany | Object,key:any,val:any):any{defineReactive(ob.value,key,val)ob.dep.notify()return val
}3.2 Object.assign()
直接使用Object.assign添加到对象的新属不会触发更新需要新建一个对象合并源对象与混入对象的属性
this.oldObjectObejct.assign({},this.onlObject,{newProperty1:1,newProperty2:2,...})3.3 $forceUpdate
看名字就知道了强制更新迫使Vue实例重新渲染进影响实例本身和插入插槽内容的子组件
4. 总结
如果要添加少量 的新属性用Vue.set()如果要添加大量的新属性Object.assign()如果你就想然他跟新那干脆$forceUpdate但是建议少用