Manipulating array in vue3 using v-model [edited]

Viewed 55

The question has three parts revolving around two files App.vue and X Array.vue :-

1.When value of input is changed, how it could be written back to the array?

2.If the value entered is empty how to remove the element from array?

3.How to show one extra input element always so that it is possible to add new values(linked with 2)?

XArray should basically be an array editor.

App.vue

    <template>
       <div>
        <XArray v-model="myArray" />
        <pre>{{ myArray }}</pre>
      </div>
    </template>

    <script>
     import XArray from './components/XArray.vue';

     export default {

     components: {
       XArray,
      },

     data: () => {
     return {
      myArray: ['one', 'two'],
            };
       },
     };
     </script>

XArray.vue

    <template>
      <input
       v-for="(option, index) in modelValue"
       :key="index"
       @input="$emit('update:modelValue', [...modelValue, `${$event.target.value}`])" 
       />
    </template>

    <script>
     export default {
     props: {
       modelValue: {
         type: Array,
         required: true,
       },
     };
    </script>
1 Answers

Please take a look at following snippet:

const app = Vue.createApp({
  data() {
    return {
      myArray: ['one', 'two'],
    }
  },
  methods: {
    addEl() {
      this.myArray.push('new')
    }
  }
})

app.component('child', {
  template: `
  <div>
    <input
       v-for="(option, index) in modelValue"
       :key="index"
       @input="$emit('update:modelValue', upd(index, $event.target.value))" 
       :value="option"
     />
   </div>
  `,
  props: {
    modelValue: {
      type: Array,
      required: true,
    }
  },
  methods: {
    upd(idx, val) {
      return val ? [
        ...this.modelValue.map((item, i) =>
          i !== idx
            ? item
            : val
        ),
      ] : this.modelValue.length > 1 ? 
            [ ...this.modelValue.filter((item, i) => {
              if(i !== idx) return item
            })] : 
            [ "last" ]
    }
  }
})

app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <child v-model="myArray"></child>
  <pre>{{ myArray }}</pre>
  <button @click="addEl">add</button>
</div>

Related