在 Vue.js 中将对象作为道具发送并获取 TypeError 和 Warning

Posted

技术标签:

【中文标题】在 Vue.js 中将对象作为道具发送并获取 TypeError 和 Warning【英文标题】:Sending object as a props in Vue.js and getting TypeError and Warning 【发布时间】:2021-12-26 10:56:01 【问题描述】:

我试图将一个对象传递给我的子组件,但它未定义。所以我的父组件:

<template>
    <section id="cart-page" class="row">
        <div v-for="items in cart" :key="items.product.id">
            <div class="col-lg-8 col-md-12 col-sm-12 col-xs-12">
                <div class="title">WARENKORB</div>
                <SoldTickets :items = "items"/>
            </div>
        </div>
    </section>
</template>
<script>
import image from "../../../../img/Hallenbad.jpg";
import CheckBox from "../components/CheckBox";
import SoldTickets from "../components/SoldTickets";
export default 
    components: 
        CheckBox,
        SoldTickets,
    ,
    data()
        return 
            image: image,
        ;
    ,
    computed: 
        cart() 
            return this.$store.state.cart;
        ,
    ,
;
</script>

所以我将购物车存储到 Vuex 商店中,并且我正确地使用了它,它是一个如下所示的对象:

所以我想将这个 cart.attributes.items 对象发送到 SoldTickets 组件以在组件内部显示它们。

<template>
    <div id="sold-tickets">
        <div class="card">
            <div class="sold-tickets-actions">
                <div class="sold-tickets-inner">
                    <img class="sold-tickets-image" :src="image" />
                </div>
            </div>
            <div class="sold-tickets-actions properties">
                <div class="sold-tickets-inner">
                    <div class="ticket-details">
                        <div class="ticket-prop">
                            <div class="ticket-name"> items.product_name </div>
                            <div class="ticket-type"> items.variation_name </div>
                        </div>
                    </div>
                    <DeleteButton />
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import image from "../../../../img/Hallenbad.jpg";
import DeleteButton from "./DeleteButton";
import cartHelper from "../helpers/cartHelper";

export default 
    props: 
        items: Object,
    ,
    components: DeleteButton,
    data() 
        return 
            image: image,
        ;
    ,
;
</script>

但我遇到了错误。 vue.esm.js:628 [Vue 警告]:渲染错误:“TypeError: Cannot read properties of undefined (reading 'id')”TypeError: Cannot read properties of undefined (读“id”)。如果这次我从父组件中删除 ':key="items.product.id"' 我会收到警告但无法再次显示项目。 [Vue 警告]:无效的道具:道具“项目”的类型检查失败。预期的对象,得到值为“00e84ffb-1fbf-00bf-d3cc-adbcc795e060”[Vue 警告] 的字符串:无效的道具:道具“项目”的类型检查失败。预期对象,得到值为“carts”的字符串

但问题是,如果我尝试在父组件中显示项目,它会在没有警告和错误的情况下工作。那么为什么你认为它正在发生呢?感谢您的帮助。

【问题讨论】:

【参考方案1】:

这里的问题是项目是一个对象数组,从 console.log() 可以看出,但你在代码中将它视为一个对象。您可以通过将某个对象传递给子组件来更改它,如下所示:

        <div v-for="items in cart" :key="items.product.id">
            <div class="col-lg-8 col-md-12 col-sm-12 col-xs-12">
                <div class="title">WARENKORB</div>
                <SoldTickets :items = "items[0]"/>  --> only pass first object
            </div>
        </div>

或者您将子组件更改为接受数组,然后像这样在模板中循环遍历数组:

<template>
    <div id="sold-tickets">
        <div class="card">
            <div class="sold-tickets-actions">
                <div class="sold-tickets-inner">
                    <img class="sold-tickets-image" :src="image" />
                </div>
            </div>
            <div v-for="item in items" :key="item.product.id" class="sold-tickets-actions properties">
                <div class="sold-tickets-inner">
                    <div class="ticket-details">
                        <div class="ticket-prop">
                            <div class="ticket-name"> item.product_name </div>
                            <div class="ticket-type"> item.variation_name </div>
                        </div>
                    </div>
                    <DeleteButton />
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import image from "../../../../img/Hallenbad.jpg";
import DeleteButton from "./DeleteButton";
import cartHelper from "../helpers/cartHelper";

export default 
    props: 
        items: Array,
    ,
    components: DeleteButton,
    data() 
        return 
            image: image,
        ;
    ,
;
</script>

【讨论】:

【参考方案2】:

问题是你正在循环遍历对象cart,它有很多键,它们的一些值是strings(例如:“00e84ffb-1fbf-00bf-d3cc-adbcc795e060”),同时您的子组件期望接收对象的时间。这就是为什么它吐出错误。您可以在此处阅读有关List Rendering with an Object 的更多信息。

我的建议:

如果您的子组件中需要cart.attributes.items,那么只需发送它,将您的计算属性cart 更改为数组:

computed: 
    cart() 
        return this.$store.state.cart.attributes?.items || [];
    

在模板中,将item数组传递给子组件,变量item应该是单数形式,你可以随意命名,但为了清楚起见,请使用单数形式:

<div v-for="item in cart" :key="item.id">
        <div class="col-lg-8 col-md-12 col-sm-12 col-xs-12">
            <div class="title">WARENKORB</div>
            <SoldTickets :item = "item"/>
        </div>
    </div>

别忘了修改你的 props 声明:

props: 
    items: Array,

【讨论】:

以上是关于在 Vue.js 中将对象作为道具发送并获取 TypeError 和 Warning的主要内容,如果未能解决你的问题,请参考以下文章

在 React-router Link 中将对象作为道具传递

如何在 Vue.js 中将实例化的 Vue 组件作为道具传递?

如何在vue中将不同值的数组作为道具传递

是否可以在 React 中将条件作为道具发送?

需要在React中将其作为道具发送之前将数据提取到数组中

Vue.js - 如何将 prop 作为 json 数组传递并在子组件中正确使用?