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方法,以便监听属性变化。- 如果目标对象存在指定属性,则直接修改属性的值。

浙公网安备 33010602011771号