您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 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
属性不会触发视图更新。
类似地,直接通过索引修改数组元素:
this.items[0] = newValue // 不会触发视图更新
this.$set(target, propertyName/index, value)
methods: {
addUserProperty() {
this.$set(this.user, 'age', 25)
// 等价于Vue.set(this.user, 'age', 25)
}
}
methods: {
updateItem(index) {
this.$set(this.items, index, {name: '新值'})
}
}
在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
}
defineReactive
转为响应式data() {
return {
form: {
username: '',
}
}
},
methods: {
addField(fieldName) {
this.$set(this.form, fieldName, '')
}
}
editRow(index, row) {
this.$set(this.tableData, index, {...row, editing: true})
}
data() {
return {
project: {
info: {
title: '项目A'
}
}
}
},
methods: {
addDetail() {
this.$set(this.project.info, 'details', [])
}
}
Vue.set()
this.$set()
// 错误方式(不会触发更新)
this.user = Object.assign({}, this.user, {age: 25})
// 正确方式
this.user = Object.assign({}, this.user)
this.$set(this.user, 'age', 25)
// 需要重新赋值整个对象
this.user = {...this.user, age: 25}
// 错误用法
this.$set(this, 'newProperty', value)
// 正确做法
this.newProperty = value // 根级别属性本身就是响应式的
频繁使用$set
可能影响性能,对于批量操作建议:
// 不如一次性替换对象
const newObj = {...this.obj, a: 1, b: 2}
this.obj = newObj
在Vue 3中使用Proxy后,可以直接添加新属性:
// Vue 3中有效
this.user.age = 25 // 自动响应
data() {
return {
user: {
name: '',
age: null // 预先声明
}
}
}
this.$set(this.deepObject, 'level1',
JSON.parse(JSON.stringify(newData)))
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
的使用频率较高,特别是在处理动态表单、表格编辑等场景时尤为重要。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。