vue2-给data动态添加属性

vue2-给data动态添加属性

1. 问题的来源

  • 在VUe2中(VUE3中使用了proxy,及时动态添加也能实现响应式),如果我们动态给data添加一个属性,会发现视图没有同步更新
  • 举个例子
  • 我们通过v-for遍历data中的一个属性list,生成一系列的div标签
  • 然后有一个按钮,点击按钮增加一个data的属性list的子项,
  • 当我们点击按钮时,会发现并没有多一个div出来
html 复制代码
<div v-for="(item,index) in list">{{item}}</div>
<button @click="addProperty">动态添加属性</button>
<script>
    const app=new Vue({
        data(){
            return{
                list:{
                    name:'tom'
                }
            }
        },
        methods:{
            addProperty(){
                this.list.age=12//为list动态添加新属性
                console.log(this.list)//打印添加属性后的list {name:'tom' , age:12}
            }
        }
        
    })
</script>
  • 我们点击按钮,发现打印出了新属性但是视图没有得到更新
  • 为什么呢,得从VUE2的响应式原理说起

2. 原理分析

  • 在VUE2中,响应式是通过Object.defineProperty来实现的
js 复制代码
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同样是响应式的额。且出发视图更新
js 复制代码
function set(target:Array<any> | Object,key:any,val:any):any{
    defineReactive(ob.value,key,val)
    ob.dep.notify()
    return val
}

3.2 Object.assign()

  • 直接使用Object.assign添加到对象的新属不会触发更新,需要新建一个对象,合并源对象与混入对象的属性
js 复制代码
this.oldObject=Obejct.assign({},this.onlObject,{newProperty1:1,newProperty2:2,...})

3.3 $forceUpdate

  • 看名字就知道了,强制更新,迫使Vue实例重新渲染,进影响实例本身和插入插槽内容的子组件

4. 总结

  1. 如果要添加少量 的新属性,用Vue.set()
  2. 如果要添加大量的新属性,Object.assign()
  3. 如果你就想然他跟新,那干脆$forceUpdate,但是建议少用
相关推荐
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端