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,但是建议少用
相关推荐
雪隐20 分钟前
个人电脑玩AI-16让5060 Ti给你打工——5060Ti 16G 跑 MiniMax-Music-3:从下载到 60s 出歌的全流程
前端·人工智能·后端
张元清1 小时前
React useLatest Hook:在异步回调里读到最新状态 (2026)
javascript·react.js
CAD老兵1 小时前
让 AI Coding Agent 直接访问 CAD 文档:GitMCP 实战指南
前端·人工智能·github
程序员鱼皮2 小时前
DeepSeek Harness 最新邪修曝光!被吹成核弹的极简模式,真的夯吗?
前端·后端·ai编程
袅沫2 小时前
Nginx中部署多个前端项目——区分路径
服务器·前端
Asize2 小时前
为什么写代码前要先规划组件树?Next.js + Redis 笔记系统实战
前端·javascript·next.js
meilindehuzi_a2 小时前
Next.js 全栈基础实战:从 SPA、SSR 到 App Router 与 Todo API
开发语言·javascript·ecmascript
用户921080262862 小时前
6. 数据大屏 WebSocket 稳定性优化:心跳检测、断点续传和消息去重
前端
柚yuzumi2 小时前
CSS 定位布局:让元素各就各位
前端·css
光影少年2 小时前
react navite图片加载优化、大图卡顿、缓存策略
前端·react native·react.js