修改数据页面不更新的原因
当vue中data里声明或者已经赋值过的对象、数组时,向对象中添加新的属性,如果更新此属性的值,页面不会更新视图。
举个例子:当我点击按钮想要改变message中的值时
此时当我点击按钮,页面并不会发生改变。
官方定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
Vue官方文档给我们提供了两种方法:Vue.set()和this.$set()
两种方法作用一样,参数也是一致的。
区别:Vue.set 可以设置实例创建之后添加的属性,而this.$set只能设置实例创建后存在的属性
修改数据页面不更新的解决方案
1.数组数据改变时,使用某些方法操作数组,数据变了,但是视图并没改变。(页面没有监测到数据改变)
解决办法:
使用下面这些方法操作数组,其数据会被vue监测
push()、pop()、shift()、unshift()、splice()、sort()、reverse()可被vue监测到。
替换数组:
例如filter()、concat()和slice(),
这些不会改变原始数组,但是会返回一个新数组。可以用新数组替代原数组。你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
注意:
vue不能监测到一下变动的数组
(1)当利用索引直接设置一个项时,vm.items[indexOfItem] = newValue
(2)当修改数组长度是,vm.items.length = newLength
为了解决利用索引改值的问题,可以用下面两种方法:
vm.items.splice(indexOfItem, 1 , newValue)
this.$set(vm.items, , newValue)
为了解决修改数组长度问题,可以用splice:
vm.items.splice(newLength)
2.对象属性的添加或删除
由于JavaScript的限制,vue不能监测到对象属性的添加或者删除
解决办法;
动态添加一个属性
this.$set(obj, key, newValue)
vue.set(object, key, newValue)
动态添加多个属性
有时候我们需要添加多个对象属性,就需要用两个对象的属性创建一个新对象。
下面这种写法不合理
Object.assign(newObj, {
name: '小太阳',
age: 18
})
应该是下面这种写法:
let newObj = Object.assign({}, newObj , {
name: '小太阳',
age: 18
})
原因:
对象是引用类型,直接改变对象的某属性但是指向地址没变,vue不一定能监控到,所以当我们新建一个对象,就直接改变了他的指向地址。
3.vue自带的强制更新
this.$forceUpdate()
,强制视图更新
4.在data中的属性依赖某个外部变量,但是外部变量改变的情况下data中的值并没有变化。
解决:watch监控