LoginSignup
12
11

More than 5 years have passed since last update.

VueFormGenerator で柔軟にFormを自動生成する

Last updated at Posted at 2018-06-03

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"
      }
    ]
  }
}

vue_gen1.png

となり、以下のようにすると

{
  "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
      }
    ]
  }
}

vue_gen2.png

となり、切り替わっていることがわかります。

凝ったフォームの生成は厳しいですが、簡単なフォームならサーバー側の修正だけでお手軽にバリエーションを増やせそうです。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11