1. 数据监测原理
问题:修改data数据vue无法监测到改变。
执行以下方法修改数组里第一个对象的时候页面不会改变。vue没有检测到值的变化。
<script> new Vue({ el: '#root', data() { return { persons: [{ id: '001', name: '马冬梅', age: 25, sex: '女' }, { id: '002', name: '周冬雨', age: 22, sex: '女' }, { id: '003', name: '周杰伦', age: 29, sex: '男' }, { id: '004', name: '邓伦', age: 28, sex: '男' } ], } }, methods: { changeData() { this.persons[0] = {id: '001',name: 'dy',age: 21,sex: '男'}; } } }) </script>
vue监测对象数据改变
1.对象里数据改变的监测是靠get和set方法来实现的。
let data = { name: '张三', age: 20 } // 创建一个监视的实例对象,用于监视data中属性的变化 const obs = new Observer(data) //准备一个vm实例对象 let vm = {} vm._data = data = obs function Observer(obj) { //汇总对象中所有的属性形成一个数组 const keys = Object.keys(obj); //遍历 keys.forEach((k) => { Object.defineProperty(this, k, { get() { return obj[k]; }, set(val) { console.log(`${k}被改了,执行模板更新操作`); obj[k] = val } }) }) }
2.Vue里set的使用
给下面data中的student添加一个sex属性。
new Vue({ el: '#root', data() { return { student: { name: '张三', age: 18 } } } })
Vue.set(vm.student, sex, '男')
vm.$set(vm.student, sex, '男')
<script> new Vue({ el: '#root', data() { return { student: { name: '张三', age: 18 } } }, methods: { addSex() { this.$set(this.student, 'sex', '男'); Vue.set(this.student, 'sex', '男'); } }, }) </script>
注意:不能添加给data一个响应式属性。
监测数组改变的方法
vue对于通过数组索引值修改数组的方式不会监测到。
错误写法:vm._data.arr[0] = ‘aaa' vue不会监测到arr数组的改变,不会重新解析模板,页面不会发生变化。
只有通过以下七种修改数组的方法才会监测到数组发生了变化,才能重新解析模板。
- pop() 删除 数组 最后一个元素;
- shift() 删除 数组 第一个元素;
- push() 数组 最后 添加 一个 元素;
- unshift() 数组 开头 添加 一个 元素;
- sort() 数组 排序
- splice() 数组 删除 替换 插入 元素
- reverse() 数组 反转
原理:
- vue会监视data中所有层次的数据。
- 如何监测对象中的数据? 通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1). 对象中后追加的属性,Vue默认不做响应式处理 (2). 如需给后添加的属性做响应式,请使用如下API: Vue.set(target, propertyName/index, value)
或vm.$set(target, propertyName/index, value)
- 如何监测数组中的数据? 通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1). 调用原生对应的方法对数组进行更新。 (2). 重新解析模板,进而更新页面。
- 在Vue修改数组中的某个元素一定要用如下方法:
- 使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
- Vue.set()或vm.$set()
特别注意: Vue.set()和 vm.$set()不能给vm或vm的根数据对象添加属性!!!