vue2源码-十五、Vue.set方法是如何实现的
Vue.set
方法是如何实现的
vue.set
方法是vue
中一个补丁方法(正常我们添加属性是不会触发更新的,我们数组无法监控到索引和长度)如何实现的 我们给每一个对象都添加了一个 dep 属性
vue3 中不需要此方法了(当属性添加或者删除时,手动触发对象本身的 dep 来进行更新)
源码:
/** * Set a property on an object. Adds the new property and * triggers change notification if the property doesn't * already exist. */ export function set (target: Array<any> | Object, key: any, val: any): any { // 非生产环境下,如果目标对象是undefined、null或基本数据类型,则会给出警告提示 if (process.env.NODE_ENV !== 'production' && (isUndef(target) || isPrimitive(target)) ) { warn(`Cannot set reactive property on ${JSON.stringify(target)},` + ' need to wrap as raw object using `Vue.util.wrapFunctionalComponent` ' + 'or rewrite it into a data function.') } // 如果目标对象是数组,并且key是有效的数组索引,则使用splice方法替换数组元素,返回新值val if (Array.isArray(target) && isValidArrayIndex(key)) { target.length = Math.max(target.length, key) target.splice(key, 1, val) return val } // 如果key已经存在于目标对象中,则直接修改属性的值,并返回新值val if (key in target && !(key in Object.prototype)) { target[key] = val return val } // 获取响应式对象(Observer实例) const ob = (target: any).__ob__ // 如果目标对象是Vue实例或者在Vue实例上定义的根$data,则会给出警告提示并返回新值val 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 } // 如果目标对象不是响应式对象,则直接设置属性值,并返回新值val if (!ob) { target[key] = val return val } // 使用Object.defineProperty()定义新的属性,并设置getter和setter方法,以便监听属性变化 defineReactive(ob.value, key, val) // 触发响应式更新 ob.dep.notify() return val }
- 如果目标对象不存在指定属性,则使用
Object.defineProperty()
向目标对象添加新的响应式属性,并设置属性的getter
和setter
方法,以便监听属性变化。- 如果目标对象存在指定属性,则直接修改属性的值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)