Vue.set 方法原理

javascript 复制代码
function set(target, key, value) {
  // 判断是否是数组,并且 key 是一个有效的索引值
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, value)
    return value
  }
  
  // 判断 key 是否已经存在于 target 中
  if (key in target && !(key in Object.prototype)) {
    target[key] = value
    return value
  }
  
  // 获取 target 的响应式对象
  const ob = target.__ob__
  
  // 判断 target 是否是响应式对象
  if (target._isVue || (ob && ob.vmCount)) {
    // 非生产环境下发出警告,不能给 Vue 实例或根数据对象添加新的 property
    // 因为 Vue 实例是代理了根数据对象,并且 Vue.set 无法触发视图更新
    console.warn(
      'Avoid adding reactive properties to a Vue instance or its root $data ' +
      'at runtime - declare it upfront in the data option.'
    )
    return value
  }
  
  // 如果 target 不是响应式对象,直接将 key 和 value 添加到 target 中
  if (!ob) {
    target[key] = value
    return value
  }
  
  // 将 key 添加到 target 中,并将 key 设置为响应式
  defineReactive(ob.value, key, value)
  ob.dep.notify()
  return value
}

上述代码中首先判断了 target 是否是数组,并且 key 是一个有效的索引值,如果满足条件,则使用 splice 方法将 value 添加到 target 中。

接着判断了 key 是否已经存在于 target 中,如果存在,则直接更新 targetkey 的值。

然后判断了 target 是否是 Vue 实例或根数据对象,如果是,则发出警告,不能给 Vue 实例或根数据对象添加新的 property。

最后判断了 target 是否是响应式对象,如果是,则使用 defineReactive 方法将 key 添加到 target 中,并将 key 设置为响应式。

相关推荐
步步为营DotNet2 分钟前
洞悉.NET 11:ASP.NET Core 10 在构建实时协作 Web 应用的技术实践
前端·asp.net·.net
Bigger3 分钟前
mini-cc 的技能系统:给 AI 装上“专业外挂”
前端·ai编程·claude
繁星星繁5 分钟前
LangChain 初探:模型调用、链式编排与运行机制
前端·chrome·langchain
z200509307 分钟前
【linux学习】Linux 软硬链接深度解析:从 inode 到目录硬链接的那些坑
前端·chrome
编程猪猪侠11 分钟前
基于uni-app-x 与 uni-app 的安卓与 H5 双向通信完整实现
android·javascript·uni-app
competes13 分钟前
数据查询方式最左匹配原则
java·大数据·前端·人工智能·windows
光影少年23 分钟前
react中的Context 为什么会导致性能问题?
前端·javascript·react.js
ZC跨境爬虫25 分钟前
跟着 MDN 学CSS day_48:深入CSS多列布局——像报纸一样组织内容
前端·css·学习
Z_Wonderful27 分钟前
react部署更新后旧 chunk 404、用户浏览器缓存旧页面的问题与(路由跳转使用相对路径而不是绝对路径的关系)分析,并提供解决方案
javascript·react.js·缓存