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

本文主要是介绍vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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>

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

这篇关于vue中父组件异步数据通过props方式传递给子组件,子组件接收不到的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/282380

相关文章

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化