问题: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里的值,为对象的每个属性加上getter
和setter
方法,一旦这些属性对应的值更新了就会去触发对应的视图更新,而b
这个属性不是vue实例化的时候就拥有的属性,所以vue并没有对这个属性进行getter
和setter
的监听,因此无法实现双向绑定,也就无法更新视图。
但是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能够响应式地更新视图。
下面介绍使用$set
和Object.assign
方法来更新对象的方式:
- 使用
$set
方法来更新对象
在Vue.js中,可以使用$set方法来为对象设置一个新的属性,例如:
this.$set(this.obj, 'prop', value)
其中,this.obj
表示要更新的对象,prop
表示属性名,value
表示属性值。
使用$set
方法的好处是,它可以确保添加的属性是响应式的,可以触发视图的重新渲染。同时,由于$set
方法的参数是动态的,因此可以在运行时添加新的属性。
- 使用
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