Back

Technologies:

javascriptjavascript
vue.jsvue.js
avatar
Tolerim
a month ago

Rephrased sentence: Building a basic to-do list in Vue.

I am currently in the process of building a small todo list app using VueJS. However, I am facing an issue where I am unable to pass an array to the child component that is responsible for displaying the list. The parent component contains a form and a TabellaCandidati component which is supposed to display the list. Here is the code:
<template>
  <div class="container">

    <div class="row">
      <div class="col-xl-5 mx-auto">
        <form @submit.prevent="submitForm()">
          <div class="row form-group mb-2">
            <div class="col-xl-12">
              <input type="text" placeholder="Nome" v-model="stati.nome" class="form-control" @input="v$.nome.$touch" :class="{ 'is-invalid': v$.nome.$error, 'is-valid': !v$.nome.$invalid}"/>
            </div>
          </div>
          <div class="row form-group mb-2">
            <div class="col-xl-12">
              <input type="text" placeholder="Cognome" v-model="stati.cognome" class="form-control" @input="v$.cognome.$touch" :class="{ 'is-invalid': v$.cognome.$error, 'is-valid': !v$.cognome.$invalid}"/>
            </div>
          </div>
          <div class="row form-group mb-2">
            <div class="col-xl-12">
              <button type="submit" class="btn btn-success">Invia</button>
            </div>
          </div>
        </form>
        <TabellaCandidati :Candidati="Candidati"></TabellaCandidati> 
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
import { useVuelidate } from '@vuelidate/core'
import { required } from '@vuelidate/validators'
import TabellaCandidati from './TabellaCandidati.vue';

    const stati = reactive({
        nome: '',
        cognome:'',
    })
    const regole = computed(() => {
      return{
        nome: { required },
        cognome: { required },
      }
    })
    
    const v$ = useVuelidate(regole, stati)

    const Candidati = ref([]);

    const submitForm = async () =>{
      const FormValidato = await v$.value.$validate();
  
      if (FormValidato) {
        Candidati.value.push({
          id:  Math.floor(Math.random() * 100),
          nome: stati.nome,
          cognome: stati.cognome,
        })
      }

    }
</script>

<p>Child component:</p>
<template>
    <table class="table">
        <thead>
            <tr>
            <th scope="col">#</th>
            <th scope="col">Name</th>
            <th scope="col">Surname</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(Candidato, index) in Candidati" :key="Candidato.id">
                <th scope="row">{{ index + 1 }}</th>
                <td>{{ Candidato.nome }}</td>
                <td>{{ Candidato.cognome }}</td>
            </tr>
        </tbody>
    </table>
    
</template>

<script setup>
    import { defineProps } from 'vue';

    const { Candidati } = defineProps(['Candidati']);
</script>

<p>I'd appreciate any insight into why I am unable to pass the array to the child component. Thank you for your help!</p>
'
Answers(2)
avatar
Vogi
a month ago
Verified Answer
It seems that you are trying to pass an array from the parent component to the child component. In Vue.js, you can pass data from the parent component to the child component using props. Props are custom attributes that can be registered on a component. When a value is passed to a prop attribute, it becomes a property on that component instance. Here is an example of how you can pass an array from the parent component to the child component: In the parent component:
&lt;div&gt;
    &lt;child-component :myArray="myArray"&gt;&lt;/child-component&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      myArray: ['item1', 'item2', 'item3'],
    };
  },
};
&lt;/script&gt;
In the child component:
&lt;div&gt;
    &lt;ul&gt;
      &lt;li v-for="item in myArray" :key="item"&gt;{{ item }}&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  props: {
    myArray: Array,
  },
};
&lt;/script&gt;
In this example, we have created a myArray property in the parent component's data object and passed it as a prop to the child component using :myArray="myArray". In the child component, we have defined a myArray prop with type Array. We can then use this prop in the child component's template using v-for. I hope this helps! Let me know if you have any other questions.

Sources

Props | Vue.jsPassing data to components in vue.js - Stack OverflowCan't pass an array to child component when using vue-routerVueJs Parent Child Communication – vegibitHow to pass an array of objects to child component in VueJS 2.xHow to use props to pass data to child components in Vue 3
avatar
Tolerim
a month ago
It seems like you are trying to destructure the Candidati prop in the child component using const {Candidati} = defineProps(['Candidati']);. However, it seems that you are losing reactivity in doing so, and you are seeing the error message "Destructuring the props will cause the value to lose reactivity". To fix this issue and retain reactivity, you can simply use the props object directly in the child component without destructuring it. Here's an example of how you can modify your child component code:
<template>
    <table class="table">
        <thead>
            <tr>
                <th scope="col">#</th>
                <th scope="col">Name</th>
                <th scope="col">Surname</th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="(candidato, index) in Candidati" :key="candidato.id">
                <th scope="row">{{ index + 1 }}</th>
                <td>{{ candidato.nome }}</td>
                <td>{{ candidato.cognome }}</td>
            </tr>
        </tbody>
    </table>
</template>

<script setup>
    import { defineProps } from 'vue';

    const props = defineProps({
        Candidati: {
            type: Array,
            required: true,
        },
    });
</script>
In this example, we are using the props object to define the Candidati prop in the child component and specifying that it is required and of the type Array. We are then using the v-for directive to iterate over the Candidati array and display each item in a table row. In the parent component, you are already passing the Candidati prop correctly to the child component using :Candidati="Candidati" in the template.
;