Vue3子组件无法监听props中数组

5,989 阅读1分钟

问题记录

背景

vue3中子组件通过watch监听父组件传递过来的数组

/* 
    父组件
*/
<template>
    <son :pipe="Pipe"/>
</template>
...
<script lang="ts" setup>
import { reactive } from 'vue';

const Pipe: Array<number> = reactive([]);
// 父组件中执行的都是push、pop,没有涉及变量地址修改
</script>
/*
    子组件
*/
<script lang="ts" setup>
import { watch, PropType } from 'vue';

const props = defineProps({
    pipe: {
        required: true,
        type: Array as PropType<Array<number>>
  }
});

// 下面这种写法不能监听pipe
watch(
    () => props.pipe,
    () => {
        ...
    }
);
</script>

上面子组件在监听props.pipe的时候用了一种箭头函数的写法,但是props.pipe只在create的时候变化(引用地址变化),其它时候都不改变,所以没有触发watch。

解决办法

因为父组件使用了动态props,pipe在父组件中的声明经过reactive包装,也是响应式的,所以可以直接一点:

watch(
    props.pipe,
    () => {
        ...
    }
);

或者这样写,watch会将props.pipe变成函数执行的一个依赖(pipe改变的时候触发getter,...会生成新地址,然后被监听到):

watch(
    () => [...props.pipe],
    () => {
        ...
    }
);