自学内容网 自学内容网

vue3 父组件 props 异步传值,子组件接收不到或接收错误

1. 使用场景

我们在子组件中通常需要调用父组件的数据,此时需要使用 vue3 的 props 进行父子组件通信传值。

2. 问题描述

那么此时问题来了,在使用 props 进行父子组件通信时,因为数据传递是异步的,导致子组件无法成功获取数据,若此时父组件中数据发生变化,那子组件获取的值是改变之前的数据。

举个 🌰:

父组件中有一个 tab 进行切换导航,下面的输入框区域为子组件,“个人” clueScope 为 1,“团队” clueScope 为 2,将父组件中的 clueScope 通过 props 传递给子组件,此时会出现下面的结果:

最开始控制台输入一行“个人”的 clueScope,接下来我们点击“团队”输出 1,点击“个人”输出 2,原因是我们在子组件获取的是父组件传递的数据更新之前的值,意识到这个很重要。

这么说有点抽象,简单看一下局部的代码:

父组件

const queryForm = ref({
    clueScope: 1, // 默认为 个人 -- 1
  }
)
const ChildRef = ref();
const renderTab = () => (
  <div>
    <ElTabs v-model={queryForm.value.clueScope} onTabChange={handleChangeTab}>
      <ElTabPane label='个人' name='1' />
      <ElTabPane label='团队' name='2' />
    </ElTabs>
  </div>
);
// 切换 tab
const handleChangeTab = () => {
  ChildRef.value.resetForm();
;
return () => (
  <div class=''>
    {renderTab()}
    <ChildComp
      ref={ChildRef}
      clueScopeType={queryForm.value.clueScope}
    />
  </div>
);

子组件使用 expose 抛出方法,让父组件进行调用。

props: {
  clueScopeType: {
    type: Number,
    default: ClueListTabEnum.个人私池,
  },
},
const resetForm = () => {
  console.log(props.clueScopeType, 'type');
}
expose({
  resetForm,
});

此时就会出现上述问题。

3. 原因

使用 props 进行父子组件通信时,子组件异步获取父组件传递的数据,也就是说,子组件还未获取父组件改变之后的数据,就已经开始执行函数,输出的就是父组件改变之前的值,因此无法成功渲染数据拿到真实值。

4. 解决方法

方法一:watch

最常见的方法就是使用 watch 进行监听,当数据发生改变之后,在执行某项操作。

// 子组件添加 watch
watch(() => props.clueScopeType, (newValue) => {
  console.log(props.clueScopeType, 'type');
})

注意 ⚠️:

一般在实际项目开发中,不建议使用 watch,因为后续可能会有其他的功能也涉及到 tab 的变化做一些操作,这样可能会出现逻辑上的耦合,如果我们把多个相互不耦合的函数,都放在一个 watch 里面,那监听的变量越来越多,这个 watch 函数也会越来越大,越来越不好控制,违背了程序的初衷。

方法二:传递参数

沿用刚刚的 resetForm 方法进行修改。

我们在父组件中传递具体的参数值,子组件中可以顺利获取,原因是,在调用函数的时候,父组件传递的值一定是改变后的值,那么子组件获取的也一定是真实的值。

// 父组件
// 切换 tab
const handleChangeTab = () => {
  RouteSearchRef.value.resetForm(queryForm.value.clueScope);
};
// 子组件
const resetForm = (type) => {
  console.log(type, 'type');
}
expose({
  resetForm,
})

以上两个方法都可以成功解决,大家可以根据实际问题具体选择哪一种。


原文地址:https://blog.csdn.net/weixin_52648900/article/details/140688137

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!