51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

vue3 中父子组件数据传输踩坑

本文最后更新于 2024-10-24,文章内容可能已经过时。

问题背景 {#问题背景}

最近在开发 halo 插件过程中,遇到了一个这样的问题,后台使用的 vue3 框架,其中涉及到了父子组件传值,带着 vue2 的开发习惯,对子组件绑定了后端异步获取的数据,以及相应事件,由子组件来渲染获取到的数据。并处理相应逻辑。父子组件代码如下:

  • 父组件
  <PasteShareSettingEditingModal v-model:isUpdateStatus="isUpdateMode" @update:pasteShare="querySaveRecord"
         v-model:visible="settingModal" :pasteShareContent="formState" @close="settingModalClose" />
  • 子组件
// 接收父组件传递过来的数据
const props = withDefaults(
  defineProps<{
    visible: boolean;
    isUpdateStatus: boolean;
    pasteShareContent?: PasteShareContent;
  }>(),
  {
    visible: false,
    isUpdateStatus: false,
    pasteShareContent: undefined,
  }
);
// 定义子组件触发的事件,通知父组件修改相应的数据
const emit = defineEmits<{
  (event: "update:visible", value: boolean): void;
  (event: "update:pasteShare", value: object): void;
  (event: "close", value: boolean): void;
}>();

上边的代码看着没问题,但是在实际使用中出现了问题:父组件通过 props 传递给子组件的数据更新时,子组件无法及时更新数据并渲染视图。

问题分析 {#问题分析}

只使用 defineProps 来接收父组件传递的数据是不够的,子组件在其一系列生命周期中是不能获取到数据的,父子组件的生命周期流程如下:

父组件 onBeforeMount ---> 子组件 onBeforeMount ---> 子组件 onMounted ---> 父组件 onMounted

如果一开始在父组件的 onBeforeMount中获取数据时,子组件此时还未挂载,是无法获取到数据的,

解决方案 {#解决方案}

1、使用 v-if 控制子组件的挂载时机 {#1-使用-v-if-控制子组件的挂载时机}

<CodeEditor v-if="flag" v-model="codeShare.content" ></CodeEditor>
const initCodeEditor = () => {
  console.log('父组件created')
  getOasteShareById(props.pasteShareId).then(res => {
    flag.value = true //获取到数据改变flag
    console.log('父组件获取到数据')
  })
}
initCodeEditor();

2、使用计算或侦听方法来处理接收的数据 {#2-使用计算或侦听方法来处理接收的数据}

// 比如使用监听父组件传递的 isUpdateStatus
watch(
  () => props.isUpdateStatus,
  (val) => {
    if (val && !formState.value.spec?.title && !currentPasteShare.value) {
      if ("title" in formState.value.spec) {
        formState.value.spec.title = "未命名代码段";
      }
      handleSavePasteShare().then(() => {
        emit("update:pasteShare", { name: formState.value.metadata.name, isFirstPublish: false });
      });
    }
  },
  { immediate: true }
);
赞(1)
未经允许不得转载:工具盒子 » vue3 中父子组件数据传输踩坑