Update model when part of array vue3

38 views Asked by At

How do I update an array when the model is in a loop for that array:

eg I have an array const numbers = ref([1,2,3]);

and I have a component that loops through the array using the values as the model:

<test v-for="(number, index) in numbers" :key="`${index}-${number}`" :number="number" @update:number="updateNumbers"></test>

If I update the number in that component:

emit('update:number', 5);

Why does it not update my original array?

Full code:

//Main page
<script>
  import {
    defineComponent,
    ref
  } from 'vue'
  import Test from './Test.vue'
  export default defineComponent({
    name: 'app',
    components: {
      Test,
    },
    setup() {
      const numbers = ref([1, 2, 3]);
      const updateNumbers = () => {
        console.log(numbers.value);
      };

      return {
        numbers,
        updateNumbers
      };
    },
  });
</script>

<template>
  <test v-for="(number, index) in numbers" :key="`${index}-${number}`" :number="number" @update:number="updateNumbers"></test>
</template> 



// Child Compnent
<script>
  import {
    defineComponent,
    ref
  } from 'vue'
  export default defineComponent({
    name: 'test',
    props: {
      number: {
        default: () => 0,
        required: true,
        type: Number,
      },
    },
    emits: [
      'update:number',
    ],
    setup(props, {
      emit
    }) {
      const updateNumber = () => {
        emit('update:number', 5);
      };

      return {
        updateNumber
      };
    },
  });
</script>

<template>
  <div @click="updateNumber">click {{ number }}</div>
</template>

Working example on vue playground

If you click the text, I would expect the original array to have it's value replaced by 5 in the console.log?

2

There are 2 answers

0
Pete On BEST ANSWER

It looks like you cannot use the a v-for and v-model together on the same element.

If I use a v-for with an index on a parent element, I can then pass the indexed property of the array in to the child as the v-model:

<div v-for="(number, index) in numbers" :key="`${index}-${number}`">     
    <test  v-model:number="numbers[index]" @update:number="updateNumbers"></test>
</div>

Updated vue playground

2
Sombriks On

You code is working fine, event payload is properly passed, you just did nothing with it.

If your intention was to emulate v-model behavior you must use modelValue as property: https://vuejs.org/guide/components/v-model.html

See updated playground here enter image description here