VueFormGenerator は、schemaからFormを自動生成するライブラリです。
本家のサンプルでは、schemaをフロントエンド側で定義していますが、サーバーからschema情報を送ることでフロントエンドを変更することなく、いろんなフォームを作成できます。
サンプル
vue側の実装は以下のような感じです。
<template>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">Dynamic Form: {{type}}</div>
<div class='panel-body'>
<vue-form-generator :schema='schema' :model='model' :options='formOptions'></vue-form-generator>
</div>
<button class="btn btn-primary" v-on:click="send">Submit</button>
</div>
</div>
</template>
<script>
import axios from 'axios'
import VueFormGenerator from 'vue-form-generator'
import 'vue-form-generator/dist/vfg.css'
import Vue from 'vue'
Vue.use(VueFormGenerator)
VueFormGenerator.validators.resources.fieldIsRequired = '必須項目だよ'
VueFormGenerator.validators.resources.textTooSmall = '短すぎ!! : 今{0}文字, 最低{1}文字入力してね'
export default {
mounted: function () {
var that = this
const url = '/api/' + this.type
axios.get(url).then(function (response) {
that.model = response.data.model
that.schema = response.data.schema
})
},
data () {
return {
model: null,
schema: null,
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
},
type: this.$route.query.type
}
},
methods: {
send: function (evnet) {
alert('POST /' + this.type + ' body:' + JSON.stringify(this.model))
}
}
}
</script>
全体はgithub においてます。
https://github.com/ihgs/sample-vue-form-geneartor
詳細
- vue-form-generator コンポーネントを定義し、
<script>
内で、schema
,model
,formOptions
を定義します。
<vue-form-generator :schema='schema' :model='model' :options='formOptions'></vue-form-generator>
-
model
,schema
は、サーバーから取得するのでnull
にしておきます。
type
:サーバーの取得データを切り替えるために、今回はパスのquery を利用します。
data () {
return {
model: null,
schema: null,
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
},
type: this.$route.query.type
}
}
-
/api/{type}
から取得した値を、model
,schema
にセットします。
mounted: function () {
var that = this
const url = '/api/' + this.type
axios.get(url).then(function (response) {
that.model = response.data.model
that.schema = response.data.schema
})
}
- validation のエラー文は、以下のようにして上書き可能です。
resource 名は、ソースで確認しましょう。
VueFormGenerator.validators.resources.fieldIsRequired = '必須項目だよ'
VueFormGenerator.validators.resources.textTooSmall = '短すぎ!! : 今{0}文字, 最低{1}文字入力してね'
動作
サーバーから返す値を以下のようにすると
{
"model":{
"id": 1,
"name": "John Doe",
"password": "J0hnD03!x4"
},
"schema": {
"fields":
[
{
"type": "input",
"inputType": "text",
"label": "ID (disabled text field)",
"model": "id",
"readonly": true,
"disabled": true
},
{
"type": "input",
"inputType": "text",
"label": "Name",
"model": "name",
"placeholder": "Your name",
"featured": true,
"required": true,
"validator": "string"
},
{
"type": "input",
"inputType": "password",
"label": "Password",
"model": "password",
"min": 6,
"required": true,
"hint": "Minimum 6 characters",
"validator": "string"
}
]
}
}
となり、以下のようにすると
{
"model":{
"skills": "Javascript",
"email": "john.doe@gmail.com",
"status": true
},
"schema": {
"fields":
[
{
"type": "select",
"label": "skills",
"model": "skills",
"values": [
"Javascript",
"VueJS",
"CSS3",
"HTML5"
]
},
{
"type": "input",
"inputType": "email",
"label": "E-mail",
"model": "email",
"placeholder": "User's e-mail address",
"validator": "email"
},
{
"type": "checkbox",
"label": "Status",
"model": "status",
"default": true
}
]
}
}
となり、切り替わっていることがわかります。
凝ったフォームの生成は厳しいですが、簡単なフォームならサーバー側の修正だけでお手軽にバリエーションを増やせそうです。