父组件传给子组件的对象,属性为undefined(解读:父组件异步获取数据传递给子组件,子组件无法得到值)

7 篇文章 0 订阅

父组件异步获取数据传递给子组件,子组件无法得到值

场景

当我将父组件从服务端异步获取的数据传给子组件的时候,子组件里面显示不了对象的属性

代码:
父组件:NewsView

<template>
	<div class="home">
		<h1>好文精选</h1>
		<News :item="newsArray[1]"></News>
	</div>
</template>

<script lang="ts" setup>
import { IArticle } from "@/types"
import { onBeforeMount, ref } from "vue"
import { news } from "../services/api"
import News from "../components/News.vue"
let newsArray = ref<IArticle[]>([])
onBeforeMount(async () => {
	try {
		let res = await news()
		if (res.stat === "OK") {
			newsArray.value = res.rows
		}
	} catch (error) {
		console.log(error)
		console.log("服务器错误")
	}
})
</script>

子组件:News

<template>
	<div>
		<div>{{ item.title }}</div>
		<div>{{ item.author }}</div>
	</div>
</template>

<script lang="ts" setup>
import { IArticle } from "../types"
import { defineProps, onBeforeMount } from "vue"
const props = defineProps<{
	item: IArticle
}>()
onBeforeMount(() => {
	console.log(props)
})
</script>

<style lang="scss" scoped></style>

结果:

在这里插入图片描述

问题

根据上述结果得出问题:

  1. 页面显示不出数据:报错
  2. 当你的父组件传给子组件的数据为异步向服务端请求的数据时,子组件刚开始打印出来的为空值,后来才是正确的值

原因

针对页面上显示不出来数据,是因为没有传递过来的对象,默认是一个空对象,里面没有属性
针对props刚开始获取的为undefined(观察结果图,发现控制台输出了两次props中获取的数据,第一次item为undefined,第二次就是正确的值),这是因为异步向服务器请求数据,数据还没来之前,子组件已经渲染到了页面上,里面item的值就是默认值,也就是undefined

解决办法

针对页面的显示,我们只需要给item附上默认值即可
针对js代码中获取到的数据为undefined,我们使用监听即可,对props中的item进行监听,如果有值了就可以进行后续操作

代码:

<template>
	<div>
		<div>{{ item.title }}</div>
		<div>{{ item.author }}</div>
		<hr />
	</div>
</template>

<script lang="ts" setup>
import { IArticle } from "../types"
import { defineProps, onBeforeMount, watch, withDefaults } from "vue"
// 设置默认值
const props = withDefaults(
	defineProps<{
		item: IArticle
	}>(),
	{
		item: () => {
			return { id: "", title: "", time: "", avatar: "", author: "", banner: "", likes: 0, comments: 0, content: "" }
		},
	}
)
// 使用监听来获取异步后面响应回来的数据
watch(
	() => props.item,
	(val, preval) => {
		console.log(val)
	},
	{
		immediate: true,
		deep: true,
	}
)
</script>

<style lang="scss" scoped></style>

注意:如果是遍历数组,生成子组件的话,就不会有这个问题,因为v-for是异步的,前提是数组里有值才能遍历生成子组件,所以生成子组件的时候一定是传递了正确的数据过去的

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值