JSFiddle - React, Tailwind, and code Playground

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div id="app">
  <form @submit="submit" action="#" method="post">
    <template v-for="schema in schemas">
      <component :is="schema.component" v-bind="schema.bind" v-model="record[schema.name]"></component>
    </template>
    <button>Enviar</button>
  </form>
  <hr>
  <pre><div v-for="entry in log" v-html="entry"></div></pre>
</div>

CSS

body {
  padding: 10px;
}

JavaScript

bootstrap()

const schemas = {
  description: {
    name: 'description',
    component: 'field-input',
    bind: {
      label: 'Descrição',
      default: ''
    }
  }
}

const record = Object.keys(schemas).reduce((accumulate, key) => {
	if (!schemas[key].bind) {
  	return accumulate
  }
  accumulate[key] = schemas[key].bind.default
  return accumulate
}, {})

new Vue({
  el: '#app',
  data: () => ({
  	schemas,
  	record,
  	log: []
  }),
  methods: {
    submit($event) {
    	this.log.push(`Save ${JSON.stringify(this.record)}`)
      $event.preventDefault()
    }
  }
})


function bootstrap() {
	Vue.component('field-input', {
  	name: 'field-input',
    props: {
      label: {
        type: String
      },
      value: {
      	default: () => (undefined)
      }
    },
    template: '<div class="form-group">' +
        '<label>{{ label }}</label>' +
        `<input class="form-control" :value="value" @input="$emit('input', $event.target.value)"/>` +
      '</div>'
  })
}