0


Vue中的$set

项目场景:

例如:在我写前端项目的时候,后端给我们的一个json对象,并且我已经渲染在页面上了。但是由于我自己的需求,想往返回的对象里面添加一个字段,后来才意识到不是响应式的。如果我们要让这个新字段是响应式的,就要使用到this.$set来注入数据。

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


问题描述

话不多说,上demo:

<!--先看一个例子--><template><div class="hello"><div>{{list}}</div><button @click="add">age++</button></div></template><script>
export default{
  name:'HelloWorld',data(){return{
      list:{name:'LL'}}},
  methods:{add(){if(!this.list.age){
        this.list.age=18}else{
        this.list.age++}
       console.log(this.list)}}}</script><style scoped></style>

当我们没有使用

this.$set

去添加对象属性时,效果图如下:
新属性age确实已经添加,但页面list并未重新渲染到视图层上,页面并没有响应式的渲染age属性
在这里插入图片描述

当我们使用了

this.$set

来添加对象属性:

add(){if(!this.list.age){// this.list.age=18this.$set(this.list,'age',18)}else{this.list.age++}
      console.log(this.list)}

在这里插入图片描述
我们可以发现这时候添加的数据就变成响应式数据了。


原因分析:

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

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

Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。例如:

var vm =newVue({data:{a:1}})// `vm.a` 是响应式的

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

解决方案:

使用:

Vue.set( target, propertyName/index, value )
参数:

{Object | Array} target
{string | number} propertyName/index
{any} value
返回值:设置的值

数组:

this.$set(Array, index, newValue)

注意:这里数组使用的是通过索引来修改会替换值。

对象:

this.$set(Object, 'Key', Value)

注意:这里对象是通过键名来进行修改和操作,所以需要用sting格式。

补充:

有时你可能需要为已有对象赋值多个新 property,比如使用 Object.assign() 或 _.extend()。但是,这样添加到对象上的新 property 不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的 property 一起创建一个新的对象。

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`this.someObject = Object.assign({},this.someObject,{a:1,b:2})

更多相关请看官网Vue响应式原理


本文转载自: https://blog.csdn.net/qq_45851085/article/details/125064876
版权归原作者 Du-eng 所有, 如有侵权,请联系我们删除。

“Vue中的$set”的评论:

还没有评论