目录
一、问题
二、解决方法
三、总结
tiips:如嫌繁琐,直接移步总结即可!
一、问题
1.真是奇怪呀,一般来说通过 push方法改变 数组,是一定会有响应式的,那就可以监听到变化。但是我今天却遇到了一件奇怪的事情。在父组件中修改了 editTableData,子组件中却监听不到变化。在<template>中显示editTableData也是被修改了的,数组长度确实也改变了,但就是监听不到 editTableData的变化!
二、解决方法
1.怀疑自己写的监听不对,但是仔细检查发现刚开始是可以监听到呀,监听代码应该是正确的。
1)代码如下:
<template>
<div class="table">
<el-table :data="targetEditTableData"> </el-table>
</div>
</template>
<script>
import { defineComponent, watch,ref } from 'vue';
export default defineComponent({
props: {
//表格数据
editTableData: {
type: Array,
default: () => {
return [];
}
}
},
setup(props) {
const targetEditTableData = ref(props.editTableData);
const checkData = () => {
let tempData = [];
//一些逻辑处理
targetEditTableData.value = tempData;
};
watch(
props.editTableData,
(newVal, oldVal) => {
console.log('watch editTableData', newVal, oldVal);
if (newVal) {
targetEditTableData.value = newVal;
}
},
);
return {
targetEditTableData,
checkData
};
}
});
</script>
2.还发现checkData没有执行前,虽然监听不到 editTableData变化,但是targetEditTableData是正常变化的。真奇怪,为什么呢?
1)发现后发现:因为一个开始我写了
const targetEditTableData = ref(props.editTableData);
没有执行checkData前,targetEditTableData就是editTableData的引用,所以editTableData变化后,targetTableData也一起变化了。
执行checkData后,targetEditTableData被重新赋值,所以不会随editTableData变化。——所以我才希望监听 editTableData的变化,赋值给targetEditTableData,可是:为什么监听不到变化呢?
3.找了半天,不知道问题:监听里面加了{deep:true}后,竟然可以监听到了!!!
4.为什么会这样呢? 刚开始以为是我的数据结构是一个对象数组,太复杂了,所以监听不到,
但是自己测试了简单的数组,push后依然监听不到变化!!!!
[
{
id: 1,
data: [{ id: '11' }, { id: '22' }]
},
{
id: 2,
data: [{}]
}
]
5.查看官方文档侦听器 | Vue.js后发现原因是:
1)监听的是:响应式对象的 getter 函数;只有当返回不同的对象时,才会触发回调。我使用editTableData.push其实没有改变 eidtTableData,所以监听不到变化。
2)解决方法:
a.添加{deep:true}
watch(
() => props.editTableData,
(newVal, oldVal) => {
console.log('watch editTableData', newVal, oldVal);
if (newVal) {
targetEditTableData.value = newVal;
}
},
{
deep:true,
}
);
b.直接监听响应式属性 editTableData
watch(
props.editTableData,
(newVal, oldVal) => {
console.log('watch editTableData', newVal, oldVal);
if (newVal) {
targetEditTableData.value = newVal;
}
},
);
3)官网描述
三、总结
1.上述问题:因为一开始editTableData和targetTableData是同一个引用,所以没有问题;后面targetTableData变化了,editTableData也变化了,只能通过监听editTableData来改变targetTableData。
2.当响应式对象的引用不变化时,需要通过 deep:true或 直接监听响应式属性(深度监听)才能监听到变化。只有对象的引用变化是时,才可以通过响应式对象的getter函数监听到。
3.要改变刻板印象,并不是使用arr.push更新的arr就能够监听变化。arr.push只能保证arr依然是响应式的。
/*
希望对你有帮助!
如有错误,欢迎指正,非常感谢!
*/