Vue中this.$set如何为data中某一对象添加一个属性

发布时间:2021-08-30 16:02:22 作者:小新
来源:亿速云 阅读:136
# Vue中this.$set如何为data中某一对象添加一个属性

## 一、前言

在Vue.js开发过程中,我们经常需要动态地向响应式对象添加新属性。然而,直接通过`obj.newProperty = value`的方式添加属性时,Vue无法检测到这种变化。这时就需要使用`this.$set`方法来实现响应式更新。本文将深入探讨`this.$set`的工作原理、使用场景以及具体实现方式。

## 二、为什么需要this.$set

### 1. Vue的响应式原理
Vue通过`Object.defineProperty`实现数据响应式,这个API只能追踪已存在的属性。当给对象添加新属性时:
```javascript
data() {
  return {
    user: {
      name: '张三'
    }
  }
},
methods: {
  addAge() {
    this.user.age = 25 // 非响应式
  }
}

这样添加的age属性不会触发视图更新。

2. 数组变异方法的限制

类似地,直接通过索引修改数组元素:

this.items[0] = newValue // 不会触发视图更新

三、this.$set的基本用法

1. 方法签名

this.$set(target, propertyName/index, value)

2. 对象属性添加示例

methods: {
  addUserProperty() {
    this.$set(this.user, 'age', 25)
    // 等价于Vue.set(this.user, 'age', 25)
  }
}

3. 数组元素修改示例

methods: {
  updateItem(index) {
    this.$set(this.items, index, {name: '新值'})
  }
}

四、实现原理剖析

1. 源码位置(Vue 2.x)

src/core/observer/index.js中:

export function set(target, key, val) {
  // 处理数组情况
  if (Array.isArray(target) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, val)
    return val
  }
  
  // 处理已存在属性
  if (key in target && !(key in Object.prototype)) {
    target[key] = val
    return val
  }
  
  // 处理新增属性
  const ob = target.__ob__
  if (!ob) {
    target[key] = val
    return val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}

2. 关键步骤解析

  1. 数组处理:通过splice变异方法触发更新
  2. 已有属性:直接赋值
  3. 新增属性:通过defineReactive转为响应式
  4. 手动触发依赖通知

五、常见使用场景

1. 动态表单字段

data() {
  return {
    form: {
      username: '',
    }
  }
},
methods: {
  addField(fieldName) {
    this.$set(this.form, fieldName, '')
  }
}

2. 表格行编辑

editRow(index, row) {
  this.$set(this.tableData, index, {...row, editing: true})
}

3. 嵌套对象处理

data() {
  return {
    project: {
      info: {
        title: '项目A'
      }
    }
  }
},
methods: {
  addDetail() {
    this.$set(this.project.info, 'details', [])
  }
}

六、与类似API的对比

1. Vue.set vs this.$set

2. 与Object.assign的区别

// 错误方式(不会触发更新)
this.user = Object.assign({}, this.user, {age: 25})

// 正确方式
this.user = Object.assign({}, this.user)
this.$set(this.user, 'age', 25)

3. 与扩展运算符对比

// 需要重新赋值整个对象
this.user = {...this.user, age: 25}

七、注意事项

1. 不能用于根数据对象

// 错误用法
this.$set(this, 'newProperty', value)

// 正确做法
this.newProperty = value // 根级别属性本身就是响应式的

2. 性能考量

频繁使用$set可能影响性能,对于批量操作建议:

// 不如一次性替换对象
const newObj = {...this.obj, a: 1, b: 2}
this.obj = newObj

3. Vue 3的替代方案

在Vue 3中使用Proxy后,可以直接添加新属性:

// Vue 3中有效
this.user.age = 25 // 自动响应

八、最佳实践

  1. 初始化时声明所有可能属性(用null占位)
data() {
  return {
    user: {
      name: '',
      age: null // 预先声明
    }
  }
}
  1. 复杂结构使用深拷贝
this.$set(this.deepObject, 'level1', 
  JSON.parse(JSON.stringify(newData)))
  1. 结合计算属性
computed: {
  userWithAge() {
    return {...this.user, age: this.user.age || 0}
  }
}

九、总结

this.$set是Vue 2.x中解决动态属性响应式更新的关键API,其核心原理是通过defineReactive将新属性转为getter/setter形式。虽然Vue 3中由于Proxy的使用不再需要此方法,但在当前Vue 2项目中仍是必备技能。正确使用$set可以避免许多响应式数据更新的”坑”,希望本文能帮助开发者更好地理解和运用这一重要特性。 “`

注:本文实际约1750字,可根据需要增减示例或调整详细程度。在Vue 2.x项目中,this.$set的使用频率较高,特别是在处理动态表单、表格编辑等场景时尤为重要。

推荐阅读:
  1. this.$set怎么在vue中使用
  2. Vue报TypeError: this.$set is not a function错误怎么办

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue

上一篇:Linux基础命令swapon的用法

下一篇:PHP如何实现浮点比较大小

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》