无法循环通过 Vue 3 Reactive Array 道具(代理)
Posted
技术标签:
【中文标题】无法循环通过 Vue 3 Reactive Array 道具(代理)【英文标题】:Unable to loop through Vue 3 Reactive Array prop (proxy) 【发布时间】:2021-06-06 05:39:23 【问题描述】:任务
我正在开发一个产品市场。每个产品都有一个 ID 和一堆与每个产品相关的信息。
有一个产品包装的概念,它只是一个产品,它是其他产品的捆绑。
在 GET PACKAGES 响应中,有一组与此包中的产品相关的 ID。在页面的其他位置,我请求产品列表,所以我已经有了我需要的数据,我只需要连接两个数据集。
该任务涉及在 UI 中显示包,以及通过两个数据集之间的 ID 连接的每个产品的描述(在 GET PRODUCTS 的另一个响应中)。
设置说明
我有一个父组件,它调用 GET PRODUCTS 和 GET PACKAGES。
我将包传递给可重用的 Vue 组件,以在 UI 中显示该包的基本信息。除此之外,我还将所有产品传递给组件,以便我们可以在包 UI 的预览中显示正确的产品描述。
问题
当将产品列表传递给子组件时,我可以完美地在控制台记录整个产品数组,但是第二次我尝试循环遍历它们(通过 MAP 或 FOREACH)没有任何反应。循环内没有控制台日志;这就像循环甚至没有运行。
父组件代码
<package
v-for="package in packages"
:key="package.id"
:packages="package"
:products="products"
></package>
// I get both sets of data in beforeOnMount and push it to the below variables
const packages = reactive<Array<Package>>([]);
const products = reactive<Array<Product>>([]);
子组件代码
props:
packages: Object as () => Package,
products: Object as () => Array<Product>
setup(props)
const uiPackages= reactive<Array<IPackageDetails>>([]);
const productData = props.products;
// This console log's a Proxy, with the handler containing an array of objects perfectly fine.
console.log(productData);
if (productData)
// This console log's undefined
console.log(productData[0]);
productData.forEach((product) =>
// This does NOTHING in console!
console.log(product)
子组件中productData的控制台日志
【问题讨论】:
clinAppData
是在哪里定义的?控制台有错误吗?
我已经更新了这些名称,因为它们是错误的,谢谢
【参考方案1】:
当子组件初始化时,products
prop 仍然是一个空数组。您在控制台中看到数据的原因是,当您单击控制台时控制台会自行更新,此时父级的异步请求已完成。
这只发生在引用中,因此您在记录时看不到没有引用的单个数组项product[0]
。
在道具上使用watch
(或watchEffect
)等待获取项目:
setup(props)
const productData = props.products;
watch(() => productData.length, () =>
productData.forEach((item) =>
console.log(item)
)
)
或者,您可以在父级中使用v-if
:
<template v-if="packages.length && products.length">
<package
v-for="package in packages"
:key="package.id"
:packages="package"
:products="products"
></package>
</template>
【讨论】:
太棒了 - 你会认为我在应用程序的其他地方不需要 watch 方法这一事实只是 API 返回响应的速度比页面需要数据的速度快吗? 我们也可以通过将子组件包装在父级的 v-if 中来避免 watch 方法,以防止组件在数据准备好之前加载? 1) 如果在别处指的是模板:模板会响应式更新,因此您暂时不会注意到它没有长度(并且它永远不会尝试访问元素)。 2) 是的,我更喜欢v-if
,而不是每个孩子的额外代码。虽然有时向孩子展示加载图形可能会很好,具体取决于。
我在答案中添加了v-if
sn-p。以上是关于无法循环通过 Vue 3 Reactive Array 道具(代理)的主要内容,如果未能解决你的问题,请参考以下文章
Vue 3 组件重置不会重置 reactive() 对象数据
Vue 3 之:弄清 ref reactive toRef toRefs