问题:vue2修改对象属性值,数据改变,但是页面视图不更新

目的:修改对象node的child属性的值,页面响应式变化
问题:数据是变了,但是页面没反应;在页面中用v-if绑定这个值,数据变了,视图也是不更新

错误写法:
this.node.child = ""
正确写法:
 this.$set(this.node, "child", "");

双向绑定的修改数据机制

我们使用v-if是一个双向绑定的过程 v-if:"isCommentShow[i]"
vue对于双向绑定的监视,是通过特定的方式实现的。如果双向绑定的对象是基本类型,则不影响。而如果双向绑定的变量是一个对象,是一个具有多个属性的对象,则需要响应式的绑定。
vue实现对对象的双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)设置属性值(set)的操作来实现的。如果要给对象添加新的属性,此时新属性没有进行过上述过程,是不会响应的。
我们如果直接修改变量的值,即this.变量 = 新值这种方式是没有经历重写的set方法的。双向绑定是没办法监听到我们的修改的。所以当我们修改了,输出的也是新值。但是你要让双向绑定知道你修改了才行,不是你改了,双向绑定就立刻知道你改了。
也就是我们需要用vue的规则去改,去通过对象重写的set方法去改对象的属性来达到响应式修改,能够立刻通知到双向绑定的指令,我修改了。
这个规则就是:this.$set(this.对象,属性名,新值)

总结

v-if不要绑定数组元素,无效,数组元素内容的变化无法响应v-if
v-if绑定对象属性 {1: true, 2: false},如果提前写死,v-if绑定其中一个属性,则可以生效v-if
如果对象的属性数量不定,是通过某方法的触发去改变对象的属性数量。需要使用$set()去更改对象的值, 如:

//增改都适用
this.$set(this.对象名, 属性名, 新值)


//不可以使用下面的方法更新
this.对象.属性 = 新值
//或者
this.对象[属性] =

只要所有修改或者增加属性的语句都使用this.$set() ,就能解决 v-if 无法响应对象中动态变化的属性的问题。
————————————————
原文链接:https://blog.csdn.net/NineWaited/article/details/126258442
未整理

使用了this.$set,数据更新了,页面依旧不更新(vue2

  • 就是说今天出现了另一个问题,使用了this.$set(),控制台打印出来数据更新了,但是页面视图没有更新

问题重现:

export default {
  data() {
    return {
      node: {
       a: ""
      },
    }
  },
  method:{
  // 这里是先执行了其他操作,在里面给node增加了一个属性b 并赋值了  this.node.b="bbb" 这样,然后使用了ondelete进行删除
  	ondelete(){
  		this.$set(this.node,"b","")
    }

这里执行之后的结果是,在控制台打印,数据是更新了,但是页面视图没有更新

解决

1.先this.$delete
2.再this.$set

this.$delete(this.node, 'b')
this.$set(this.node, 'b', '')

这样数据和视图就都更新了

原因

执行这段代码会发现视图上并没有更新b的值,但是控制台里可以打印出来。这就设计到ES5中的Object.defineProperty方法了,这个方法有一个缺点就是不能监听到对象或数组属性的增加或删除,就导致了这一现象的发生。

vue中的双向数据绑定就是用这个方法实现,vue在创建实例的时候,会遍历data里的值,为对象的每个属性加上gettersetter方法,一旦这些属性对应的值更新了就会去触发对应的视图更新,而b这个属性不是vue实例化的时候就拥有的属性,所以vue并没有对这个属性进行gettersetter的监听,因此无法实现双向绑定,也就无法更新视图。

但是this.$ set 方法还有另一种情况,就是当你要设置的key已经存在于这个对象或数组中的时候,它只会更改data并不会为该key添加响应检测,所以页面上的依赖b的试图就不会更新,解决这个问题的办法就是在设置值之前先把这个属性删除掉,然后再进行this.$set

this.$delete(this.node, 'b')
this.$set(this.node, 'b', '')

所以其实可以现在data中申明一下??? data(){node:{a:“”,b:“”}} 这样??? 下次看看

搜集的问题

   <div id="app">
      <ul>
        <li v-for="item in obj">
          {{ item }}
        </li>
      </ul>
      <button @click = addObj>添加Obj</button>
    </div>

var vm = new Vue({
      el: "#app",
      data: {
        obj: {
          a: "obj.a"
        }
      },
      methods: {
          addObj() {
            this.obj.b = 'obj.b'
            //this.$set(this.obj, 'b' ,'obj.b')
              console.log(this.obj)
          }
      }
    });

在这里插入图片描述

可以看到obj对象中成功添加了属性b,值为‘obj.b’ 但是,并没有同步渲染到页面上,这是因为Vue最初实例化的时候,Obj中没有属性b,故而如果用this.obj.b添加属性的话Vue不会把他作为响应式监听。
所以应该要使用this.$set(‘对象名’,要修改的属性名,属性值),这样新添加的属性值会被Vue监听到并且同步渲染到页面上,需要注意的是数组也是同样的
————————————————
原文链接:https://blog.csdn.net/qq_39776508/article/details/88789158

其他

Vue.js在监听一个对象的属性变化时,会通过其Setter方法进行响应式更新。但是,当一个对象被创建后,Vue.js无法动态追踪到对象属性的添加和删除,因此,直接通过obj.prop = value的方式给对象添加或修改属性时,这些属性不会触发视图的重新渲染。因此,需要使用一些特定的方法来修改对象属性,以确保Vue.js能够响应式地更新视图。

下面介绍使用$setObject.assign方法来更新对象的方式:

  1. 使用$set方法来更新对象
    在Vue.js中,可以使用$set方法来为对象设置一个新的属性,例如:
this.$set(this.obj, 'prop', value)

其中,this.obj表示要更新的对象,prop表示属性名,value表示属性值。

使用$set方法的好处是,它可以确保添加的属性是响应式的,可以触发视图的重新渲染。同时,由于$set方法的参数是动态的,因此可以在运行时添加新的属性。

  1. 使用Object.assign方法来更新对象
    Object.assign方法用于将多个对象的属性合并到一个对象中,可以使用该方法来更新对象,例如:
this.obj = Object.assign({}, this.obj, { prop: value })

其中,this.obj表示要更新的对象,{ prop: value }表示要新增或修改的属性。

使用Object.assign方法的好处是,它可以一次性修改多个属性,并且可以使用ES6的扩展运算符...来快速添加多个属性。

需要注意的是,这两种方法都是通过创建一个新的对象来更新对象的属性,而不是直接修改原始对象的属性,因此需要重新给对象赋值。如果直接使用赋值运算符=来更新对象的属性,可能会导致该属性的值不是响应式的,从而无法触发视图更新。因此,尽量避免直接修改对象的属性,使用$set或者Object.assign方法来更新对象,可以保证对象的响应式更新。
————————————————
原文链接:https://blog.csdn.net/xxxzzzqqq_/article/details/129355514