watch的基本使用方法
watch:{ watchData: function (value, oldValue) { console.log(value, oldValue) } },
以上情况针对的是简单数据类型,比如数字,字符串,布尔类型等。若遇到复杂类型,如对象、数组,就需要使用深度监听
watch的深度监听
背景:普通的监听只能监听简单类型,如果需要监听某个对象的某个或者某几个属性,亦或者是监听数组中的某个元素变化,就需要使用深度监听
watch:{ newTableData: { handler: function (value, oldValue) { console.log(value, oldValue) }, deep: true } },
使用上面的语法,会造成oldValue的值在每次newTableData变化时,都和value保持一致,变成当前最新的值,失去了oldValue的作用
原因:
vue官方解释是:在变异 (不是替换) 对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变异之前值的副本。
Tips:变异和替换
变异
push() | 往数组最后面添加一个元素,成功返回当前数组的长度 |
pop() | 删除数组的最后一个元素,成功返回删除元素的值 |
shift() | 删除数组的第一个元素,成功返回删除元素的值 |
unshift() | 往数组最前面添加一个元素,成功返回当前数组的长度 |
splice() | 有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值 |
sort() | sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组 |
reverse() | reverse() 将数组倒序,成功返回倒序后的数组 |
替换
不会改变原数组,但总是返回一个新数组
filter | filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。 |
concat | concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组 |
slice | slice() 方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组 |
解决方法
使用序列化和反序列化
将计算属性和侦听器搭配使用,
1.首先将需要侦听的属性通过JSON.parse和stringfy进行深拷贝,
2.然后用侦听器去侦听计算属性,这样就可以得到原来的旧值了
data: () { return{ // 数据为复杂类型 tableAll:{ tableData:[] } } }, computed:{ // 使用计算属性进行深拷贝 newTableData(){ return JSON.stringify(this.tableAll.tableData) } }, watch:{ // 监听拷贝后的数据 newTableData: { handler: function (value, oldValue) { let obj = JSON.parse(value); let obj2 = JSON.parse(oldValue); console.log(obj, obj2) }, deep: true } }