♥ 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’)

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

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: