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()向目标对象添加新的响应式属性,并设置属性的gettersetter方法,以便监听属性变化。
  • 如果目标对象存在指定属性,则直接修改属性的值。
posted @   楸枰~  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示