Vue – form – the introduction of the generator
JSON dynamic form development solution, click to view the source code github. The implementation logic of vue-form-Generator is disassembled in detail below.
JSON Schema structure
{
fields: [{type: "input".inputType: "text".label: "First Name".model: "first_name".attributes: {
input: {
"data-toggle": "tooltip"
},
wrapper: {
"data-target": "input"}}}, {type: "submit".buttonText: "Change Previous Type".attributes: {
input: {
"data-target": "toggle"}},onSubmit: () = > {
// this.schema.fields[2].type = "input";
if (this.schema.fields[2].inputType === "color") {
this.schema.fields[2].inputType = "text";
} else {
this.schema.fields[2].inputType = "color"; }}}]}Copy the code
Implementation logic for dynamic forms
Step 1: Introduce dynamic form components
<vue-form-generator :schema="schema" :model="model" :options="formOptions" ref="form" :is-new-model="isNewModel" @model-updated="modelUpdated" @validated="onValidated"></vue-form-generator>
Copy the code
Step 2: Vue-form-generator component source code
<template lang="pug">div.vue-form-generator(v-if='schema ! = null') fieldset(v-if="schema.fields", :is='tag') template(v-for='field in fields') form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated") //- Form group template(v-for='group in groups') fieldSet (:is='tag', :class='getFieldRowClasses(group)') legend(v-if='group.legend') {{ group.legend }} template(v-for='field in group.fields') form-group(v-if='fieldVisible(field)', :vfg="vfg", :field="field", :errors="errors", :model="model", :options="options", @validated="onFieldValidated", @model-updated="onModelUpdated")</template>
Copy the code
Component is implements dynamic rendering of form element components
<template>
<div class="form-group" :class="getFieldRowClasses(field)">
<label v-if="fieldTypeHasLabel(field)" :for="getFieldID(field)" :class="field.labelClasses">
<span v-html="field.label"></span>
<span v-if='field.help' class="help">
<i class="icon"></i>
<div class="helpText" v-html='field.help'></div>
</span>
</label>
<div class="field-wrap">
<! Implement dynamic rendering of form element components -->
<component ref="child" :is="getFieldType(field)" :vfg="vfg" :disabled="fieldDisabled(field)" :model="model" :schema="field" :formOptions="options" @model-updated="onModelUpdated" @validated="onFieldValidated"></component>
<div v-if="buttonVisibility(field)" class="buttons">
<button v-for="(btn, index) in field.buttons" @click="buttonClickHandler(btn, field, $event)" :class="btn.classes" :key="index" v-text="btn.label" :type="getButtonType(btn)"></button>
</div>
</div>
<div v-if="field.hint" class="hint" v-html="fieldHint(field)"></div>
<div v-if="fieldErrors(field).length > 0" class="errors help-block">
<span v-for="(error, index) in fieldErrors(field)" :key="index" v-html="error"></span>
</div>
</div>
</template>
Copy the code
Step 4: Form element component implementation (example: Input)
<template lang="pug">
.wrapper(v-attributes="'wrapper'")
input.form-control(
:id="getFieldID(schema)",
:type="inputType",
:value="value",
@input="onInput",
@blur="onBlur",
:class="schema.fieldClasses",
@change="schema.onChange || null",
:disabled="disabled",
:accept="schema.accept",
:alt="schema.alt",
:autocomplete="schema.autocomplete",
:checked="schema.checked",
:dirname="schema.dirname",
:formaction="schema.formaction",
:formenctype="schema.formenctype",
:formmethod="schema.formmethod",
:formnovalidate="schema.formnovalidate",
:formtarget="schema.formtarget",
:height="schema.height",
:list="schema.list",
:max="schema.max",
:maxlength="schema.maxlength",
:min="schema.min",
:minlength="schema.minlength",
:multiple="schema.multiple",
:name="schema.inputName",
:pattern="schema.pattern",
:placeholder="schema.placeholder",
:readonly="schema.readonly",
:required="schema.required",
:size="schema.size",
:src="schema.src",
:step="schema.step",
:width="schema.width",
:files="schema.files"
v-attributes="'input'")
span.helper(v-if="schema.inputType.toLowerCase() === 'color' || schema.inputType.toLowerCase() === 'range'") {{ value }}
</template>
Copy the code