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>'
})
}