Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

antoine_l's avatar

Passing an array prop into `ref()` doesn't work

Hello,

I'm learning Vue and I don't understand why passing an array property into a ref() doesn't seem to work.

Here is an example to illustrate my question :

Shopping.vue

<template>
    <h3>Choose fruits:</h3>
    <ul>
        <li v-for="fruit in fruits" :key="fruit.name">
            <input
                type="checkbox"
                :id="fruit.name"
                v-model="selectedFruits"
                :value="fruit"
            >
            <label :for="fruit.name">
                {{ fruit.name }} (from {{ fruit.country }})
            </label>
        </li>
    </ul>

    <hr>

    <Cart :products="selectedFruits" />
</template>

<script setup>
import { ref } from "vue";
import Cart from "@/Components/Cart";

const fruits = [
    {name: 'Apple', country: 'Canada'},
    {name: 'Avocado', country: 'Mexico'},
    {name: 'Strawberry', country: 'Spain'},
];

const selectedFruits = ref([]);
</script>

Cart.vue

<template>
    <h3>In your cart:</h3>
    <ul>
        <li v-for="product in products">
            {{ product.name }} from ({{ product.country }})
        </li>
    </ul>
</template>

<script setup>
import { ref } from "vue";

const props = defineProps({
    products: Array
});

const products = ref(props.products);
</script>

Because I'm doing const products = ref(props.products), my cart list doesn't list the products. If I directly loop on my prop (without creating a const products) it works. Why?

Thank you!

0 likes
7 replies
tykus's avatar

You have a prop and a ref with the same name products; change one of them! For example, if your Cart component accepts a data-products prop:

<Cart :data-products="selectedFruits" />

you can use a ref named products

<script setup>
import { ref } from "vue";

const props = defineProps({
    dataProducts: Array
});

const products = ref(props.dataProducts);
</script>
antoine_l's avatar

@tykus Thank your for your answer! Actually I tried this earlier and it doesn't work either

tykus's avatar

@antoine_l what does doesn't work mean; are there errors in the console, what is the unwanted behaviour (if any)?

antoine_l's avatar

@tykus Here is my code as you suggested:

Shopping.vue

<template>
    <h3>Choose fruits:</h3>
    <ul>
        <li v-for="fruit in fruits" :key="fruit.name">
            <input
                type="checkbox"
                :id="fruit.name"
                v-model="selectedFruits"
                :value="fruit"
            >
            <label :for="fruit.name">
                {{ fruit.name }} (from {{ fruit.country }})
            </label>
        </li>
    </ul>

    <hr>

    <Cart :data-products="selectedFruits" />
</template>

<script setup>
import { ref } from "vue";
import Cart from "@/Components/Cart";

const fruits = [
    {name: 'Apple', country: 'Canada'},
    {name: 'Avocado', country: 'Mexico'},
    {name: 'Strawberry', country: 'Spain'},
];

const selectedFruits = ref([]);
</script>

Cart.vue

<template>
    <h3>In your cart:</h3>
    <ul>
        <li v-for="product in products">
            {{ product.name }} from ({{ product.country }})
        </li>
    </ul>
</template>

<script setup>
import { ref } from "vue";

const props = defineProps({
    dataProducts: Array
});

const products = ref(props.dataProducts);
</script>

When I check boxes, the list in Cart component remains unexpectedly empty. I have no console errors though.

Niush's avatar

The products prop that is passed, is already reactive. So you do not need to wrap it with another ref. You can access props.products and it will be reactive.

And, in Vue 3 with defineProps(), you can directly access props.products simply as products variable. So you do not need to re-create this variable yourself.

antoine_l's avatar

@tykus Yeah exactly, it's just a trivial example but I would like to mutate products in Cart component in real life. That's why I would like to create another ref. But I noticed it works If I directly use the prop

Please or to participate in this conversation.