vue提供了watch
方法,用于监听实例内data
数据的变化。
直接监听
1 | <template> |
1 | <template> |
直接监听对象是监听对象的指向,不能监听到某个对象里面属性的变化。
如果需要监听的数据是对象内的某一属性值的变化,直接watch
对象friend是检测不到变化的,这是因为friend这个对象的指向并没有发生改变。
1 | <script> |
直接改变对象会触发监听
1 | this.friend = { |
deep
设为了true
,修改了这个friend中的任何一个属性,都会执行handler这个方法。不过这样会造成更多的性能开销,尤其是对象里面属性过多,结构嵌套过深的时候。而且有时候我们就只想关心这个对象中的某个特定属性。
1 | <script> |
扩展:handler声明函数或函数表达式都可以,但是不能箭头函数
1 | watch : { |
没有的时候上面的例子是值变化时候,watch才执行,我们想让值最初时候watch就执行就用到了handler
和immediate
属性,immediate : true代表在wacth里声明了newA这个方法之后立即先去执行handler方法,如果设置了false,那么效果和没有一样
1 | <script> |
1 | <script> |
把对象某个属性的值修改都触发,无论改成基本类型还是引用对象,而且引用对象内vue也能监听到。
1 | // 例1:数据修改成功,视图修改成功=三种方式的属性监听都触发 |
对于已经创建的实例,Vue 不允许动态添加根级别(外层内层都监听不到)的响应式 property: 无法渲染
解决方案:
预先留出变量
使用this.$set / Vue.set()
1 | this.friend.sex = "girl"; // 数据修改但无法渲染 = 监听不到 |
Vue 无法检测 property 的移除
解决方案:
Vue.delete()删除对象某个元素后,会立即触发页面渲染:Vue.delete(propertyName/index)
1 | delete this.friend.age; //数据删除但无法渲染 = 监听不到 |
1 | <template> |
1 | <script> |
1 | // 例子1:修改成功,数组、元素都渲染成功,触发上面对数组的监听 |
例如:arr[indexOfItem] = newValue;
解决方案:
使用this.$set(arr, index, newVal)
使用splice(indexOfItem, 1, newValue):
使用临时变量直接赋值的方式,原理与直接赋值数组一样
1 | this.colors[0] = "blue"; // 不是响应的,数据修改成功但渲染不成功 = 不触发监听 |
Vue可以监听
1 | this.colors.push('yellow') // 数据添加成功,视图渲染成功 |
例如:arr.length = newLength
长度大于原数组就将后续元素设置为 undefined, 长度小于原数组就将多余元素截掉。
解决方案:
this.$set(arr, index, newVal);
使用数组 splice 方法可以监听
使用临时变量直接赋值的方式,原理与直接赋值数组一样
1 | this.colors.length = 1; // 数据修改成功,视图渲染不成功 |