vue对象改变时dom不更新如何解决,以及出现这种情况的原因。
在vue中,改变某个对象的值时(如数组中的某一项或者对象的某个属性),vue并不会触发dom更新,这时就需要我们自己手动来操作。方法一:强制刷新// 此行为会重新渲染整个dom,除数据层次太多外,不建议使用this.$forceUpdate();方法二:对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用Vue.set(object, propertyN...
在vue中,改变某个对象的值时(如数组中的某一项或者对象的某个属性),vue并不会触发dom更新,这时就需要我们自己手动来操作。
方法一:强制刷新
// 此行为会重新渲染整个dom,除数据层次太多外,不建议使用
this.$forceUpdate();
方法二:对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value)
方法向嵌套对象添加响应式属性。如:
data() {
// 数组
array: [1, 2, 3, 4];
// 对象
obj: {name: "test"},
}
......
// 这种方式赋值并不会触发dom并自动更新
// this.array[0] = 5;
// 改为此种方式赋值则会触发更新,
// 参数1:要修改的数组, 参数2:要修改的数组的索引, 参数3:修改后的值
this.$set(this.array, 0, 5);
// this.obj.name = "张三";
// 参数1:要修改的对象, 参数2:要修改的对象的属性名, 参数3:修改后的值
this.$set(this.obj, "name", "张三");
以下是出现这种情况的原因:
出现这种情况的原因是由于vue2.x的基本原理决定的。vue的基本原理是通过Object.defineProperty重写变量的get和set方法来实现监听变量的改变和通知页面重新渲染的。
这里就要了解一下Object.defineProperty,以下直接拷贝的官网文档。
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
Object.defineProperty(obj, prop, descriptor)
obj: 要定义属性的对象。
prop: 要定义或修改的属性的名称或 Symbol 。
descriptor: 要定义或修改的属性描述符。
假如你在vue中定义了一个对象:objTest: {name: "test"},
vue在created之前会重写objTest对象中name的get和set:
// 先把原来的obj深拷贝一份
var objCopy = JSON.parse(JSON.stringfy(this.obj));
var newObjTest = Object.defineProperty(objTest, 'name', {
get: function () {
// 返回objCopy的name,如果返回obj.name会死循环
return objCopy.name;
},
set: function (newValue) {
// 把objCopy的name属性重新赋值
objCopy.name = newValue;
// 去通知页面obj的name的值变了,该渲染页面了
......
}
})
从上面的例子可以看出,当我们给obj.name属性赋值的时候,会走我们重新定义的set方法,并让页面重新渲染,但是为什么有时候却不行呢?这就是Object.defineProperty的不足之处了,因为在vue中它只会遍历已有的对象及其属性,未定义的属性vue是不会重写get和set的方法的。
所以如果你在data中没有定义某个对象属性,而在后续的操作中添加了新的属性时,页面是不会重新渲染的。
更多推荐
所有评论(0)