首页 前端知识 ♥ vue中$set用法详细讲解

♥ vue中$set用法详细讲解

2024-03-24 22:03:06 前端知识 前端哥 191 198 我要收藏

♥ vue中$set用法详细讲解

1、认识

在vue中,并不是任何时候数据都是双向绑定的。

vue2是用object.definedProperty来实现数据响应的,他无法监听深层数据的变化。所以需要使用this.$set来实现数据的修改和添加。如:

`this.$set(this.test, 'text1', 'test');` 

而vue3是通过proxy代理来实现数据的响应,通过ref和reactive将值和对象类型变为响应式对象,所以这样对它的修改和添加就能被vue捕获到,从而实现页面的自动刷新。所以直接对对象本身进行修改或者添加就行了,this.$set自然就没用了

const test =reactive({
  name: 'test',
  temp:'temp',
})
const change=()=>{
  test.name='new'
}
const add=()=>{
  test.test="add"
}
const dels=()=>{
  delete test.temp
}


$set是Vue.js中用于为响应式对象添加属性的实例方法,可以在运行时向响应式对象添加新的响应式属性,并确保这些属性也是响应式的。

在Vue.js中, s e t 是用于向响应式对象添加新属性的方法,可以实现动态添加属性和修改数组元素等操作,能够确保这些属性也是响应式的。需要注意的是, set是用于向响应式对象添加新属性的方法,可以实现动态添加属性和修改数组元素等操作,能够确保这些属性也是响应式的。需要注意的是, set是用于向响应式对象添加新属性的方法,可以实现动态添加属性和修改数组元素等操作,能够确保这些属性也是响应式的。需要注意的是,set不能用于向根数据添加属性,而且不能在computed计算属性中使用

$set接收三个参数:对象、属性名和属性值

// 添加响应式属性 vue2 
this.$set(对象,'属性名',属性值); 


// 添加响应式属性 vue3
const obj = reactive({
  a: 1
})
$set(obj, 'b', 2) 

官方文档介绍

在这里插入图片描述

使用场景

当数据没有被双向绑定的时候,我们就需要使用set了`

举个例子:
vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。

2、$set作用和用法

(1)解决动态添加属性不响应的问题

在Vue.js中,如果在实例化后的响应式对象中添加新属性,则该新属性默认不会是响应式的,也就是说,如果这个属性的值发生变化,页面不会随之更新。

不生效代码案例
export default {
  data() {
    return {
      obj: { a: 1 }
    }
  },
  methods: {
    addProp() {
      this.obj.b = 2
    }
  }
}

调用addProp方法添加属性b后,页面不会响应更新,需要用$set来解决该问题

$set的解决方法
import { $set } from 'vue'
this.$set(this.obj, 'b', 2)

(2) 动态修改数组

不生效代码案例

通过改变数组元素的值和指定下标添加元素并不能触发视图更新,可以使用$set来解决该问题

export default {
  data() {
    return {
      arr: [1, 2, 3]
    }
  },
  methods: {
    change() {
      // 修改数组元素的值
      this.arr[0] = 4
      // 添加新元素到数组
      this.arr[3] = 4
      // 输出数组长度
      console.log(this.arr.length)
    }
  }
}
$set的解决方法
import { $set } from 'vue'

this.$set(this.arr, 0, 4) // 参数1为数组,参数2为下标,参数3为修改后的值
this.$set(this.arr, 3, 4)
console.log(this.arr.length) // 输出4

数据没有被双向绑定我们可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名


 - this.$set(原数组, 索引值, 需要赋的值)

length的问题还需要用splice方法

 - vm.items.splice(newLength)

set为解决双向绑定失效,所以什么时候双向绑定失效就用它

当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
由于 JavaScript 的限制,Vue不能检测对象属性的添加或删除

var vm= new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 现在是响应式的

vm.b = 2
// `vm.b` 不是响应式的

vm.a是响应式的, vm.b不是响应式的

简单来说

对象中原来有这个key=> 双向绑定
对象中原来没有这个key,新增的key=>不是双向绑定


vm.$set(con.userProfile, 'age', 27)

进一步使用

如果我们添加的属性很多条,可能就需要写一个循环来多次set
你也可能使用Object.assign,这里有一些需要注意的地方。
如果你想添加新的响应式属性,下面这样写是不行的。

Object.assign(vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

这样才是正确的

vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})


3、$set的使用注意事项

(1)对于引用类型的对象,需要递归添加属性

如果要添加的属性是一个引用对象或嵌套引用对象的属性,需要使用递归方式将添加操作完成:

// 示例代码
const obj = reactive({
  a: {
    b: 1
  }
})

// 递归添加响应式属性
$set(obj.a, 'c', 2)

( 2 ) 不能向根数据添加属性

不能使用$set添加到Vue实例根数据的属性,因为这些属性在创建Vue实例时就已经初始化,无法做到响应式处理

// 示例代码
const vm = createApp({
  data() {
    return {
      a: 1
    }
  },
  created() {
    // $set添加到根数据的属性会报错
    this.$set(this, 'b', 2)
  }
})
vm.mount('#app')

( 3 )不能在computed中使用$set

computed计算属性的返回值必须是纯函数,不能有副作用。如果在computed中使用$set方法,会破坏这个约束,可能会产生一些无法预测的错误

4、原理

————————————————————————————

Vue2 中的数据响应式是利用 object.definedProperty()实现的,它是无法深层监听数据的变化的

Vue3,利用的是ES6的proxy,对数据响应式进行一个数据的代理。

由于 Vue 会在初始化实例时进行双向数据绑定,使用Object.defineProperty()对属性遍历添加 getter/setter 方法,所以属性必须在 data 对象上存在时才能进行上述过程 ,这样才能让它是响应的。如果要给对象添加新的属性,此时新属性没有进行过上述过程,不是响应式的,所以会出想数据变化,页面不变的情况。此时需要用到$set。

向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property
(比如 this.myObject.newProperty = ‘hi’)

————————————————————————————

转载请注明出处或者链接地址:https://www.qianduange.cn//article/4085.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!