vue-form-generator简介
JSON 动态化表单开发方案,点击查看源码github。下文将详细拆解vue-form-generator的实现逻辑。
JSON Schema结构
{
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";
}
}
}
]
}
复制代码
动态表单的实现逻辑
第一步:引入动态表单组件
复制代码
第二步:vue-form-generator组件源码
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")
//- 表单组
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")
复制代码
component is 实现表单元素组件动态渲染
复制代码
第四步:表单元素组件实现(例:input)
.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 }}
复制代码
|