Starlove
Starlove

Reputation: 21

Manipulating array in vue3 using v-model [edited]

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>

Upvotes: 0

Views: 564

Answers (1)

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23490

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>

Upvotes: 1

Related Questions