Here's a method you can use to achieve that. This script loops through a counter using the v-for
directive to iterate over a range.
Vue.component('my-component', {
template: "<p>hello</p>",
})
var vue = new Vue({
el: "#App",
data: {
hellocount: 0
},
methods: {
append: function() {
// unknown code here
this.hellocount++
}
}
})
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8ef8fbebcebca0bca0b8">[email protected]</a>/dist/vue.js"></script>
<div id="App">
<my-component v-for="n in hellocount" :key="n"></my-component>
<button @click="append" class="btn btn-primary">Spawn stuff!</button>
</div>
This approach is a bit unusual; typically, you would populate the components based on real data, as suggested by @RoyJ in the comments.
As per your request below, you could create a form like this:
Vue.component('my-input', {
props:["value", "name"],
data(){
return {
internalValue: this.value
}
},
methods:{
onInput(){
this.$emit('input', this.internalValue)
}
},
template: `
<div>
{{name}}:<input type="text" v-model="internalValue" @input="onInput">
</div>
`,
})
var vue = new Vue({
el: "#App",
data: {
form:{
name: null,
email: null,
phone: null
}
},
methods:{
append(){
const el = prompt("What is the name of the new element?")
this.$set(this.form, el, null)
}
}
})
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="790f0c1c394b574b574f">[email protected]</a>/dist/vue.js"></script>
<div id="App">
<my-input v-for="(value, prop) in form"
:key="prop"
v-model="form[prop]"
:name="prop">
</my-input>
<button @click="append">Add New Form Element</button>
<div>
Form Values: {{form}}
</div>
</div>
The script creates a form object and generates input fields for each property of the form.
Of course, this is quite basic and only supports text inputs, etc. But I hope you understand the concept behind it.