vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题

2023-10-30

vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题

问题描述
组件化开发中经常用到父子组件的通信,父传子子传父等数据的操作,如果父组件的数据是发请求从后端获取的异步数据,那么父组件将这个数据传递给子组件的时候,因为是异步数据,就会出现父组件传递过去了,但是子组件mounted钩子初始情况下是接收不到的问题。本篇文章记录了一下这个问题的解决方案。

在说这个问题之前,我们先来回顾一下父子组件的生命周期

父子组件生命周期执行顺序

加载渲染数据过程父组件

beforeCreate -->
父组件 created -->
父组件 beforeMount -->
子组件 beforeCreate -->
子组件 created -->
子组件 beforeMount -->
子组件 mounted -->
父组件 mounted -->

更新渲染数据过程

父组件 beforeUpdate -->
子组件 beforeUpdate -->
子组件 updated -->
父组件 updated -->

销毁组件数据过程

父组件 beforeDestroy -->
子组件 beforeDestroy -->
子组件 destroyed -->
父组件 destroyed

可以这样理解,父组件生命周期中会先看看子组件的生命周期有没有走完,子组件生命周期走完了,才会走父组件的生命周期。

问题分析
我们模拟一下父子组件通信的过程,写个小demo。看看在子组件中的mounted钩子中能不能接收到父组件传递过来的数据

父组件代码

<template>
  <div id="app">
    <child :msg="msg"></child>
  </div>
</template>

<script>
import child from "./views/child";
export default {
  name: "App",
  components: {
    child,
  },
  data() {
    return {
      msg: "", // 我们要把父组件从接口获取的数据存到data中的msg里面,然后再传递给子组件
    };
  },
  created() {
    // 用定时器模拟发请求异步获取后端接口的数据
    setTimeout(() => {
      this.msg = "666";
    }, 200);
  },
};
</script>

子组件代码

<template>
  <div>
      <h2>{{msg}}</h2>
  </div>
</template>

<script>
export default {
    props:{
        msg:{
            type:String,
            default:''
        }
    },
    mounted() {
        console.log('mounted钩子中接收',this.msg);
    },
}
</script>

最终在mounted钩子中会实现,我们会发现打印不出来,如下图
在这里插入图片描述

当然如果是同步的数据传递给子组件,子组件的mounted钩子是能接收到,能打印出来的,这里就不演示了,因为我们做项目开发的数据大多数都输从后端的接口中获取的异步数据的。

因为父组件传递给子组件的数据,可能我们还要加工一下再使用,所以在mounted钩子中获取父组件传递过来的数据是一定要做的。那么,这里为什么mounted钩子中打印不出来父组件传递过来的数据,但是props最终接收到了,页面最终还渲染出来了么?

原因浅析

我们知道,mounted钩子默认加载只会执行一次,由于数据是要等到200毫秒以后才能拿到,那么子组件的mounted钩子执行的时候,还没有拿到父组件传递过来的数据,但是又必须要打印出来this.msg的结果,那这样的话,就只能去打印props中的msg的默认值空字符串了,所以打印的结果是一个空字符串,比如,我们在子组件中这样打印就知道this.msg是不是空字符串了

mounted() {
        console.log('mounted钩子中接收', this.msg == '');
    },

打印结果图如下
在这里插入图片描述
但是props是可以等的,是可以拿到异步的数据渲染的。所以就出现了上述的结果,有问题解决问题,接下来说一下解决这样的问题的方案

方案一 使用v-if控制子组件渲染的时机

思路其实很简单,就是初始还没拿到后端接口的异步数据的时候,不让组件渲染,等拿到的时候再去渲染组件。使用v-if="变量"去控制,初始让这个变量为false,这样的话,子组件就不会去渲染,等拿到数据的时候,再让这个变量变成true,这样的话,组件就会去渲染,此时数据也已经得到了,这样的话,在子组件的mounted钩子中就拿到父组件传过来的异步数据了。代码如下

父组件

<template>
  <div id="app">
    <child :msg="msg" v-if="isGetData"></child>
  </div>
</template>

<script>
import child from "./views/child";
export default {
  name: "App",
  components: {
    child,
  },
  data() {
    return {
      msg: "",
      isGetData:false // 初始为false,就不会被渲染对应的子组件
    };
  },
  created() {
    // 用定时器模拟发请求异步获取后端接口的数据
    setTimeout(() => {
      this.msg = "666";
      this.isGetData = true // 拿到数据以后,再把isGetData置为true,这样的话,组件就会被渲染啦,数据也就会被传递过去啦
    }, 200);
  },
};
</script>

子组件
这种方式,子组件不用动代码,在父组件中去做控制即可

但是这种方式有一个小小的缺点,就是最终效果会显得组件有些延迟才出现效果。因为异步数据是从后端的接口获取的,如果接口时间长一些的话,最终效果渲染也会慢一点,但是!!!一般情况下,后端的接口速度都会控制在几十到几百毫秒的时间,一般情况下,不会出现好几秒,甚至几十秒的接口,所以瑕不掩瑜,这种方式不影响我们使用

方案二 子组件使用watch监听父组件传递过来的数据

父组件
这种方式父组件正常传递数据即可,不需要做什么代码处理,只要在子组件中加一个监听即可

子组件

<template>
  <div>
    <h2>{{ editMsg }}</h2>
  </div>
</template>

<script>
export default {
  props: {
    msg: {
      type: String,
      default: "",
    },
  },
  watch: {
    // 监听到父组件传递过来的数据后,加工一下,
    // 存到data中去,然后在页面上使用
    msg(newnew, oldold) {
      console.log("监听", newnew, oldold);
      this.editMsg = "---" + newnew + "---";
    },
  },
  data() {
    return {
      editMsg: "",
    };
  },
};
</script>

看一下这种方式对应的效果图
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题 的相关文章

随机推荐

  • 第二章 计算机发展与应用

    计算机从诞生至今已经经历了多个阶段的发展 包括 1 电子管时代 1940年代 1950年代 计算机使用电子管作为主要的电子元件 这些计算机体积庞大 功耗大 但是它们标志着计算机的诞生 并且在二战期间被广泛应用于军事领域 2 晶体管时代 19
  • 6.2、客户/服务器方式(C/S)&对等方式(P2P方式)

    网络应用程序运行在处于网络边缘的不同的端系统上 通过彼此间的通信来共同完成某项任务 开发一种新的网络应用首先要考虑的问题就是 网络应用程序在各种端系统上的组织方式和它们之间的关系 color red 网络应用程序在各种端系统上的组织方式和它
  • TypeScript与Date类型

    js的继承方式 经典的js寄生组合式继承 function MyDate Date apply this arguments this abc 1 function inherits subClass superClass function
  • mysql5.7.17安装+mysql error:1524+1045+外部访问出错

    1 mysql5 7 17安装 windows10系统 下载mysql 5 7 17 winx64 copymysql 5 6 35 winx64的data文件 进入安装数据库目录bin cd C ProgramFiles mysql 5
  • 指数历年各月涨幅分析-验证五穷六绝七翻身是否可信

    指数通常反映了一个行业或者一类股票的行情数据 本文将对697支指数的历史各月涨幅进行分析 为量化投资作一个参考 从分析中 我们可以验证五穷六绝七翻身是否可信 并找出上涨概率最大的一些指数和月份 1 数据准备 本文程序中用到两个数据 1 in
  • clickHouse MergeTree核心原理

    1 MergeTree的创建方式与存储结构 1 1 MergeTree的创建方式 CREATE TABLE IF NOT EXISTS db table name ON CLUSTER cluster name1 type1 DEFAULT
  • C# 基础程序结构和入门实例(学习心得 2)

    超级小白友好 讲解C 基础 每集5分钟轻松学习 拒绝从入门到放弃 C Hello World 实例 C 最小的程序结构需要包含以下部分 命名空间声明 一个 class 一个 Class 方法 该 Class 方法的属性 一个 Main 方法
  • python中class的作用

    在 Python 中 class 是用来定义对象的类型的 通过定义类 可以创建该类型的多个实例 每个实例都有相同的属性和方法 类也可以继承其它类 并扩展或重写属性和方法
  • 人工智能:未来制胜之道

    在数据 算法 计算 场景驱动新一轮人工智能飞速发展 未来3 5年内人工智能将处于服务智能阶段 即技术边际突破但应用海量拓展 人工智能未来竞争格局将由生态构建者 技术算法驱动者 应用聚焦者 垂直行业先行者 基础设施提供者五类竞争定位模式主导
  • springgateway限流-令牌桶算法

    限流配置 参见 https blog csdn net forezp article details 85081162 https cloud spring io spring cloud gateway 2 2 x reference h
  • 学计算机的感想300字,大学生计算机实训心得体会3篇

    大学生计算机实训心得体会3篇 我们有一些启发后 可以通过写心得体会的方式将其记录下来 这样我们可以养成良好的总结方法 那么心得体会到底应该怎么写呢 下面是小编为大家整理的大学生计算机实训心得体会 欢迎大家分享 大学生计算机实训心得体会1 在
  • 在服务器上下载安装anaconda

    anaconda下载与安装 1 连接到服务器 进入服务器界面 同时连上网络 登录到Anaconda官网 如果你的服务器是Linux系统 选择这一款 2 打开服务器的终端 Open in Terminal 进入命令行输入 bash Anaco
  • DATAX_HOOK,怎么实现的

    DATAX HOOK 怎么实现的 JobContainer 类Datax的job执行类 JobContainer 类 An highlighted block JobContainer 类关于 finally if isDryRun thi
  • 【portainer.io】可视化界面学习

    portainer io 学习目标 学习内容 portaine背景 docker基于界面管理工具Portainer 安装portainer 启动portainer 使用portainer 学习总结 学习目标 学习内容 了解portainer
  • maven当中如何用SpringMVC和mybatis创建一个项目

    创建一个SpringMVC mybatis项目 马克 to win 马克 java社区 防盗版实名手机尾号 73203 下部我们做一个SpringMVC mybatis的例子 我们还是继续刚才项目的底子 参见我的mybatis那一章 这个例
  • 本地ecshop网站怎么上传到服务器,ECSHOP商品批量上传,ECSHOP商品数据包导入

    各位ECSHOP网店系统用户大家好 欢迎来到ECSHOP商品批量上传 ECSHOP商品数据导入设置 第一节 1 1 进入后台管理中心 商品管理 商品批量上传 进入商品批量上传页面 如图所示 1 2 您可以在上图中红色方块区域标注中下载批量上
  • linux protobuf静态库,Mac下交叉编译protobuffer版本库(C++版)

    一 前言 这几天和开发jni的同学对接SDK 其中包含了protobuffer和openssl库 这里主要说一下protobuffer编译mac环境静态库过程及遇到的问题 在此记录下来供后续参考 由于对linux及英文不是很熟 过程中也感谢
  • 如何合并多个工作表或多个工作簿?3种合并方法都在这

    分享三个方法 一分钟搞定 简单 快速 步骤少 总有一个适合你 话不多说 往下看 01 多个工作簿单张工作表的合并 如下图所示 我们有几个区域的销售数据分别放在不同的工作簿中 每个工作簿内只有一张工作表 每个工作簿的表格结构是一致的 现在我们
  • android 防止反编译的若干方法

    第一种方式 混淆策略 混淆策略是每个应用必须增加的一种防护策略 同时他不仅是为了防护 也是为了减小应用安装包的大小 所以他是每个应用发版之前必须要添加的一项功能 现在混淆策略一般有两种 对代码的混淆 我们在反编译apk之后 看到的代码类名
  • vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题

    vue中父组件异步数据通过props方式传递给子组件 子组件接收不到的问题 问题描述 组件化开发中经常用到父子组件的通信 父传子子传父等数据的操作 如果父组件的数据是发请求从后端获取的异步数据 那么父组件将这个数据传递给子组件的时候 因为是