当前位置: 首页 > 知识库问答 >
问题:

javascript - 关于vue3.2父子组件传ref数组监听问题?

祁柏
2024-02-21

代码demo:

// 父组件html:<comp v-model:tableData="tableData"></comp>js:let tableData = ref([]);// 获取评论列表async function getCommentList() {    let res = await api();    tableData.value = res.data}// 子组件js:const props = defineProps({  tableData: {    type: Array,    default: () => [],  }});watch(  ()=>props.tableData,// 为什么这里不加()=>就无法进入监听?  (newVal) => {...},  { deep: true });

请教一下子组件的watch不加()=>就无法进入监听?

共有2个答案

冯翔
2024-02-21

根据官方的API说明:

watch(WatcherSource, Callback, [WatchOptions])type WatcherSource<T> = Ref<T> | (() => T) interface WatchOptions extends WatchEffectOptions {    deep?: boolean // 默认:false     immediate?: boolean // 默认:false     flush?: string // 默认:'pre'}

因此你应该:

watch(  tableData,  (newVal) => {...},  { deep: true });

最后提醒一下:

当我们使用watch侦听引用对象时

  • 若使用ref定义的引用对象:

    • 只要获取当前值,watch第一个参数直接写成数据源,另外需要加上deep:true选项
    • 若要获取当前值和先前值,需要把数据源写成getter函数的形式,并且需对数据源进行深拷贝
  • 若使用reactive定义的引用对象:

    • 只要获取当前值,watch第一个参数直接写成数据源,可以不加deep:true选项
    • 若要获取当前值和先前值,需要把数据源写成getter函数的形式,并且需对数据源进行深拷贝
艾哲
2024-02-21

在 Vue 3 中,watch 是一个用于观察和响应 Vue 实例上的数据变化的 API。它允许你在数据变化时执行一些自定义逻辑。

对于你的问题,watch 函数的第一个参数应该是一个依赖项数组,该数组包含了你想要观察的响应式属性。在这个数组中,你可以直接使用变量名(对于局部响应式属性)或 this.$refs(对于子组件的响应式属性)。

在你的代码中,你正在尝试观察一个从父组件传递到子组件的 prop,即 tableData。由于 tableData 是通过 prop 传递的,它不是子组件的局部响应式属性。因此,你不能直接将其放入依赖项数组中。

解决这个问题的一种方法是使用箭头函数。箭头函数可以捕获定义它们的作用域中的变量,这意味着你可以在箭头函数中使用 props.tableData,而不是直接在 watch 函数中使用它。这样,当 tableData 发生变化时,箭头函数将返回新的值,从而使 watch 进入监听模式。

下面是修改后的代码:

// 子组件const props = defineProps({  tableData: {    type: Array,    default: () => [],  }});watch(  () => props.tableData, // 使用箭头函数捕获props.tableData  (newVal) => {    // 当 tableData 发生变化时执行的逻辑  },  { deep: true });

现在,当 tableData 发生变化时,watch 将进入监听模式,并执行你提供的回调函数。

 类似资料: