JSFiddle - React, Tailwind, and code Playground

by Simon Herteby

HTML

<div id="vue">
  <field v-for="(field, index) in inputQuestions"
    :key="index"
    v-bind="field"
    v-model="outputData[field.reference]">
  </field>
  <pre>{{outputData}}</pre>
</div>

Vue

Vue.component('field', {
  props:{
  	type:{type:String, required:true},
    name:{type:String, required:true},
    value:{type:[String, Number], required:true},
    options:{type:Array, default:() => []},
    placeholder:{type:String, default:''}
  },
  computed:{
  	model:{
    	get(){
      	return this.value
      },
      set(val){
      	if(typeof this.value === 'number'){
        	this.$emit('input', Number(val))
        } else {
        	this.$emit('input', val)
        }      	
      }
    }
  },
	template:`
  	<div>
    	<label>{{name}}</label>
      <textarea v-if="type === 'textarea'" v-model="model" :placeholder="placeholder"/>
      <select v-else-if="type === 'select'" v-model="model">
      	<option disabled style="display:none" :value="undefined">{{placeholder}}</option>
      	<option v-for="option in options" :value="option">{{option}}</option>
      </select>
      <template v-else-if="type === 'radio'">
      	<div v-for="option in options">
        	<input type="radio" v-model="model" :value="option">
        	<label>{{option}}</label>
        </div>
      </template>
    	<input v-else :type="type" v-model="model" :placeholder="placeholder">
    </div>  	
  `
})
new Vue({
	el:'#vue',
  data(){
  	return {
    	inputQuestions: [
      { name: 'first name', type: 'text', reference: 'firstname'},
      { name: 'last name', type: 'text', reference: 'lastname'},
      { name: 'description', type: 'textarea', reference: 'description'},
      { name: 'option', type: 'checkbox', reference: 'option'},
      { name: 'select', type: 'select', reference: 'select', options:['One','Two','Three'], placeholder:'Select something'},
      { name: 'radio', type: 'radio', reference: 'select', options:['One','Two','Three']},
    ],
    outputData: {}
    }
  }
})