温馨提示×

温馨提示×

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

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

vue $set怎么实现给数组集合对象赋值

发布时间:2022-04-26 08:20:12 来源:亿速云 阅读:1494 作者:iii 栏目:大数据
# Vue $set 怎么实现给数组集合对象赋值 ## 一、Vue 响应式原理与 $set 的诞生背景 ### 1.1 Vue 的响应式系统局限性 Vue 2.x 使用 `Object.defineProperty` 实现响应式,这种实现存在两个主要限制: 1. **无法检测对象属性的添加/删除** 2. **数组变更的特殊情况**: - 通过索引直接设置项(`arr[index] = newValue`) - 修改数组长度(`arr.length = newLength`) ### 1.2 为什么需要 $set 当我们需要动态给响应式对象添加新属性,或修改数组特定索引的值时,直接赋值不会触发视图更新。这时就需要使用 `Vue.set` 或实例方法 `this.$set`。 ```javascript // 不会触发更新 this.arr[1] = 'new value' this.obj.newProp = 'value' // 正确做法 this.$set(this.arr, 1, 'new value') this.$set(this.obj, 'newProp', 'value') 

二、$set 的核心实现解析

2.1 源码位置(Vue 2.x)

$set 方法定义在 src/core/observer/index.js 中:

export function set(target, key, val) { // 处理数组情况 if (Array.isArray(target) && isValidArrayIndex(key)) { 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.2 数组处理的特殊逻辑

对于数组操作,$set 内部实际上使用了 splice 方法,这是因为 Vue 重写了数组的变异方法(push/pop/shift/unshift/splice/sort/reverse),使得这些方法能够触发响应式更新。

// 等效操作 this.$set(arr, index, value) // 等同于 arr.splice(index, 1, value) 

三、$set 的实际应用场景

3.1 动态添加对象属性

export default { data() { return { user: { name: '张三' } } }, methods: { addAge() { // 错误方式 // this.user.age = 25 // 不会响应 // 正确方式 this.$set(this.user, 'age', 25) } } } 

3.2 修改数组元素

export default { data() { return { items: ['a', 'b', 'c'] } }, methods: { updateItem(index) { // 错误方式 // this.items[index] = 'x' // 不会响应 // 正确方式 this.$set(this.items, index, 'x') // 替代方案(同样有效) // this.items.splice(index, 1, 'x') } } } 

3.3 动态添加嵌套属性

export default { data() { return { formData: {} } }, methods: { initForm() { // 多层嵌套需要逐层设置 this.$set(this.formData, 'contact', {}) this.$set(this.formData.contact, 'phone', '') } } } 

四、$set 的替代方案比较

4.1 使用 Vue 3 的 reactive

在 Vue 3 中,基于 Proxy 的响应式系统不再需要 $set:

import { reactive } from 'vue' const state = reactive({}) state.newProp = 'value' // 自动响应 

4.2 使用 Object.assign

对于对象,可以创建新对象触发更新:

this.user = Object.assign({}, this.user, { age: 25 }) 

4.3 数组的特殊方法

对于数组,优先使用变异方法:

// 替换元素 this.items.splice(index, 1, newItem) // 添加元素 this.items.push(newItem) 

五、$set 的注意事项

  1. 不能用于根级响应式属性

    // 错误!不能直接添加根级属性 this.$set(this, 'newProp', value) 
  2. 性能考虑

    • 频繁使用 $set 可能影响性能
    • 对于批量操作,建议先处理数据再整体赋值
  3. 与 v-model 的配合: “`html

 ## 六、总结 `$set` 是 Vue 2.x 响应式系统的重要补充,它解决了以下关键问题: - 动态添加响应式属性 - 数组索引直接赋值 - 确保嵌套属性的响应性 在 Vue 3 中,由于 Proxy 的实现,大多数情况下不再需要 `$set`,但在 Vue 2.x 项目中,它仍然是处理动态响应式数据的利器。 **最佳实践建议**: 1. 初始化时尽量声明所有响应式属性 2. 必须动态添加时优先使用 `$set` 3. 数组操作优先使用变异方法 4. 复杂数据结构考虑使用 Vuex 或 Pinia 管理状态 通过合理运用 `$set` 方法,可以确保你的 Vue 应用始终保持正确的响应式行为。 
向AI问一下细节

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

AI