惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
WordPress大学
WordPress大学
IT之家
IT之家
G
Google Developers Blog
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
Engineering at Meta
Engineering at Meta
Martin Fowler
Martin Fowler
V
V2EX
爱范儿
爱范儿
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog
V
Visual Studio Blog
有赞技术团队
有赞技术团队
I
InfoQ
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网

微风静语

用 codebase-memory-mcp 给 AI 编程加一层“代码记忆” EchoCraft - 专为独立开发者和小型团队打造的产品官网主题 Halo 站长必备:外链安全与流量分析神器——“链接工具箱”重磅升级! Halo插件开发:java17旧项目迁移至java21项目记录 Halo插件|一个面向创作者的多功能媒体处理工具集 分布式事务详解:从入门到精通 让你的网站初步适配PWA Halo主题 - 微浸:以轻量构建美学,用细节定义体验 深入理解Python爬虫技术:原理、实现与实践 Halo-2.20 新特性:自定义登录页面模版 将你的服务运维面板从宝塔替换为1panel Python实战项目:外星人入侵(源码分享) theme-hao主题适配友链自助提交插件 plugin-artalk 插件保姆级使用教程 plugin-blog-hao 插件部分功能演示 halo 插件开发踩坑记录(一) Thymeleaf 模版引擎语法浅记 信息洪流中的自我救赎 mac 系统里如何管理多个jdk版本 memso API 不完全指南 基础语法:从CPU角度看变量、数组、类型、运算、跳转、函数等语法 halo-theme-hao主题:artalk评论区美化 衡量个人成长 halo-theme-hao 主题魔改教程 分享一个魔改的 Artalk 评论系统邮件模版 halo-theme-hao 主题标签记录 开发一个 Halo2.0 的安全条跳转中台插件! Mac 软件推荐:使用 Mac 一年半来,我一直在用的软件! TypeScript教程---面向对象编程 软件版本命名规范
vue3 中父子组件数据传输踩坑
webjing · 2024-10-18 · via 微风静语

问题背景

最近在开发 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 控制子组件的挂载时机

<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、使用计算或侦听方法来处理接收的数据

// 比如使用监听父组件传递的 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 }
);