当前位置:首页 > VUE

vue.set实现原理

2026-01-22 03:27:00VUE

Vue.set 的实现原理

Vue.set 是 Vue.js 提供的一个全局 API,用于向响应式对象动态添加新属性并确保新属性也是响应式的。其核心原理基于 Vue 的响应式系统。

核心机制

Vue 的响应式系统通过 Object.defineProperty 或 Proxy(Vue 3)实现数据劫持。当直接通过普通方式给对象添加新属性时,新属性不会触发响应式更新,因为 Vue 无法检测到这种变化。

Vue.set 通过以下方式解决这一问题:

  • 对于数组,使用变异方法(如 splice)触发响应式更新。
  • 对于对象,手动调用 defineReactive 方法将新属性转为响应式。

源码分析

在 Vue 2.x 源码中,Vue.set 的实现位于 src/core/observer/index.js。其主要逻辑如下:

function set (target, key, value) {
  // 处理数组情况
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, value)
    return value
  }

  // 处理对象已有属性
  if (key in target && !(key in Object.prototype)) {
    target[key] = value
    return value
  }

  // 处理新增对象属性
  const ob = target.__ob__
  if (!ob) {
    target[key] = value
    return value
  }
  defineReactive(ob.value, key, value)
  ob.dep.notify()
  return value
}

关键步骤解析

对于对象类型,Vue.set 会检查目标对象是否已被观察(即是否有 __ob__ 属性)。如果未被观察,直接赋值;如果已被观察,则通过 defineReactive 方法将新属性转为响应式。

对于数组类型,Vue.set 内部使用 splice 方法,这是 Vue 重写的数组变异方法之一,能够触发依赖更新。

与直接赋值的区别

直接给响应式对象添加新属性:

this.someObject.newProperty = 'value' // 非响应式

使用 Vue.set 添加新属性:

vue.set实现原理

Vue.set(this.someObject, 'newProperty', 'value') // 响应式

Vue 3 的变化

在 Vue 3 中使用 Proxy 实现响应式后,Vue.set 的用途大幅减少,因为 Proxy 可以自动检测新增属性。但 Vue 3 仍保留了类似功能的 set API 以保持兼容性。

标签: 原理vue
分享给朋友:

相关文章

vue请求实现进度条

vue请求实现进度条

实现请求进度条的方法 在Vue中实现请求进度条可以通过多种方式完成,常见的有使用第三方库如axios结合nprogress或自定义进度条组件。以下是几种实现方法: 使用axios和nprogress…

代码实现vue

代码实现vue

创建Vue项目 使用Vue CLI快速初始化项目,确保已安装Node.js和npm/yarn: npm install -g @vue/cli vue create my-vue-project c…

vue权限实现

vue权限实现

Vue 权限实现方案 基于路由的权限控制 通过路由守卫实现权限验证,在路由配置中添加meta字段标记权限要求。在router.beforeEach中检查用户权限与路由要求的匹配情况。 // rout…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

vue实现flvvideo

vue实现flvvideo

vue-flv-player 实现 FLV 视频播放 安装依赖包 npm install flv.js vue-flv-player 基础组件引入 <template> <v…

vue实现抽奖

vue实现抽奖

Vue 实现抽奖功能 基本抽奖逻辑 创建一个Vue组件,包含奖品列表、抽奖按钮和结果显示区域。使用随机数生成器选择奖品。 <template> <div> <…