1.关于数组
eg: arr = [1,2,3]
this.$set(this.arr,4, 20) // arr [1,2,3,null,20]
此时可以得到结论:this.$set可以修改数组并触发更新
2.关于对象
eg: obj = { name: '张三'}
this.obj.id = 4 // 页面上此时是不会刷新的
this.$set(this.obj, 'id' , 5) //页面上会刷新,显示id为5
setTimeout(()=>{ this.obj.id = 8 },5000) //页面上5s后会显示8
可以得到结论:通过this.set触发更新
3.源码解析
if (process.env.NODE_ENV !== 'production' &&
(isUndef(target) || isPrimitive(target))
) {
warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
}
//如果传入的对象是一个数组且索引是一个正常索引
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
//如果值在对象中
if (key in target && !(key in Object.prototype)) {
target[key] = val
return val
}
const ob = (target: any).__ob__
if (target._isVue || (ob && ob.vmCount)) {
process.env.NODE_ENV !== 'production' && warn(
'Avoid adding reactive properties to a Vue instance or its root $data ' +
'at runtime - declare it upfront in the data option.'
)
return val
}
if (!ob) {
target[key] = val
return val
}
defineReactive(ob.value, key, val) //加入依赖收集
ob.dep.notify() //通知更新
return val
}