父组件中 arr.push改变数组,但是子组件监听不到 arr 的变化

目录

一、问题

二、解决方法

三、总结


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依然是响应式的

/*

希望对你有帮助!

如有错误,欢迎指正,非常感谢!

*/

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-16 12:36:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-16 12:36:06       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-16 12:36:06       82 阅读
  4. Python语言-面向对象

    2024-01-16 12:36:06       91 阅读

热门阅读

  1. vue之虚拟滚动

    2024-01-16 12:36:06       59 阅读
  2. 纯c实现链表 数据结构大全

    2024-01-16 12:36:06       50 阅读
  3. Oracle sql sum函数返回null,默认值0

    2024-01-16 12:36:06       57 阅读
  4. 用Python判断节假日,以及节假日的SQL数据文件

    2024-01-16 12:36:06       49 阅读
  5. MySQL 8.0中引入的选项和变量(三)

    2024-01-16 12:36:06       46 阅读
  6. Simon算法详解

    2024-01-16 12:36:06       46 阅读
  7. 【嵌入式——C++】 程序流程结构

    2024-01-16 12:36:06       56 阅读