[Vuejs]-VueJS – input file repeater

2👍

Vue uses an “in-place patch strategy” when dealing with list of elements. This strategy is not suitable when relying on form input values.

When using v-for directive it is better to define a v-bind:key to give Vue a hint to track each node.

We’ll store numbers in the items array and use them as a key. In your case you should use an item’s property that can serve as a unique key.

let app = new Vue({
  el: '#app',
  data: {
    counter: 0,
    items: []
  },
  methods: {
    addItem() {
      this.items.push(this.counter++);
    },
    removeItem(index) {
      this.items.splice(index, 1);
    }
  }
});
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
<div id="app">

  <ul class="list-group">
    <li class="list-group-item" v-for="(item , index) in items" :key="item">
      <a href="#" v-on:click.prevent="removeItem(index)">remove</a>
      <input name="form[]" type='file'>

    </li>
  </ul>
  <button @click='addItem'>new item</button>


</div>

1👍

Your codes working fine but,
This is because of file input auto complete behaviour

See this example

let app = new Vue({
  el : '#app',
  data : {
    items: [],
  },
  methods : {
    addItem() {
      this.items.push({file: null});
      console.log(this.items)
    },
    removeItem(index) {
      this.items.splice(index,1);
    },
    handleChange(item, event){
      item.file = event.target.files["0"];
    }
  }
});
.upload-btn-wrapper {
  position: relative;
  overflow: hidden;
  display: inline-block;
  vertical-align: middle;
}
.btn {
  border: 1px solid gray;
  color: gray;
  background-color: white;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 15px;
  font-weight: bold;
}
.upload-btn-wrapper input[type=file] {
  font-size: 100px;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
}
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>

<div id="app">
  <ul class="list-group">
    <li class="list-group-item" v-for="(item , index) in items">
      <a href="#" v-on:click.prevent="removeItem(index)">remove</a>
      <div type="button" class="upload-btn-wrapper">
        <button class="btn">{{ item.file ? item.file.name : 'Choose File' }}</button>
        <input name="form[]" type="file" @change="handleChange(item, $event)">
      </div>
    </li>
  </ul>
  <button @click='addItem'>new item</button>
</div>

Leave a comment