Vue.component('my-input-broken', {
props: ['name', 'type', 'label'],
methods: {
inputHandler(e) {
this.$emit('input', e.target.value);
},
},
template: `
<div v-if="name && type" :id="name">
<input v-if="type !== 'textarea'" @input="inputHandler" :name="name" :type="type" />
<textarea v-else-if="type === 'textarea'" @input="inputHandler" @blur="blurHandler($event)" :name="name" type="textarea" />
<label v-if="label" :for="name">{{label}}</label>
</div>
`
})
Vue.component('my-input-fixed', {
props: ['name', 'type', 'label', 'value'],
methods: {
inputHandler(e) {
this.$emit('input', e.target.value);
},
},
template: `
<div v-if="name && type" :id="name">
<input v-if="type !== 'textarea'" @input="inputHandler" :name="name" :type="type" :value='value' />
<textarea v-else-if="type === 'textarea'" @input="inputHandler" @blur="blurHandler($event)" :name="name" :value='value' type="textarea" />
<label v-if="label" :for="name">{{label}}</label>
</div>
`
})
const vm = new Vue({
el: '#app',
data: function() {
return {
values: [""],
componentToUse: 'a'
}
},
methods: {
addInput() {
this.values.unshift("")
}
},
computed: {
comp() {
return this.componentToUse === 'a' ? "my-input-broken" : "my-input-fixed"
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
<label for="componentToUse">Component to use:</label>
<input type="radio" name="componentToUse" v-model="componentToUse" value="a"> Broken
<input type="radio" name="componentToUse" v-model="componentToUse" value="b"> Fixed
<hr>
<button @click="addInput">Add at beginning...</button>
<component :is="comp" v-for="(value, index) in values" :key="index" v-model="values[index]" :name="`value_${index}`" type="text" :label="`value_${index} ('${values[index]}')`"></component>
</div>