赞
踩
可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成器
轻松搞定 form 表单,让你不在为表单而烦恼
form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成器。并且支持生成任何 Vue 组件。结合内置17种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。
npm i @form-create/element-ui
npm i @form-create/iview
npm i @form-create/iview4
本节将以iview版本为例介绍如何在项目中使用 form-create
浏览器
<!-- import Vue 2.5-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<!-- import iview 2.14.3-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/iview@2.14.3/dist/styles/iview.css">
<script src="https://cdn.jsdelivr.net/npm/iview@2.14.3/dist/iview.min.js"></script>
<!-- 省市区三级联动json数据,不使用三级联动不需要引入 -->
<script src="https://cdn.jsdelivr.net/npm/@form-create/data/dist/province_city_area.js"></script>
<!-- import formCreate -->
<script src="https://cdn.jsdelivr.net/npm/@form-create/iview/dist/form-create.min.js"></script>
NodeJs
在 main.js 中写入以下内容:
import Vue from 'vue';
import iView from 'iview';
import 'iview/dist/styles/iview.css';
import formCreate from '@form-create/iview'
//获取生成器
import { maker } from '@form-create/iview'
Vue.use(iView);
Vue.use(formCreate);
可使用3种方式创建表单:
组件模式, Vue 原型方法, Window 全局方法
使用 标签创建表单
<div id="app1">
<form-create v-model="fApi" :rule="rule" :option="option"></form-create>
</div>
NodeJs
export default { data () { return { //实例对象 fApi:{}, //表单生成规则 rule:[ { type:'input', field:'goods_name', title:'商品名称' }, { type:'datePicker', field:'created_at', title:'创建时间' } ], //组件参数配置 option:{ //表单提交事件 onSubmit:function (formData) { alert(JSON.stringify(formData)); } } }; } };
浏览器
new Vue({ el:'#app1', data:{ fApi:{}, rule:[ { type:'input', field:'goods_name', title:'商品名称' }, { type:'datePicker', field:'created_at', title:'创建时间' } ], option:{ onSubmit:function (formData) { alert(JSON.stringify(formData)); } } } });
使用 vue 原型方法$formCreate(rule,option) 创建表单
<div id="app2"> <div id="form-create"></div> </div> new Vue({ el:'#app2', data:{ fApi:{}, model:{} }, mounted:function () { //表单插入的节点 const root = document.getElementById('form-create'); //fApi为表单api this.fApi = this.$formCreate( //表单生成规则 [ this.$formCreate.maker.input('商品名称','goods_name',''), this.$formCreate.maker.date('创建时间','created_at') ], //组件参数配置 { el:root, //表单提交事件 onSubmit:function (formData,fApi) { fApi.btn.loading(); } }); } })
使用 window 全局方法formCreate.create(rule,option)创建表单
<div id="app3"> <div id="form-create"></div> </div> //表单插入的节点 const root = document.getElementById('form-create'); //$f为表单api const $f = window.formCreate.create( //表单生成规则 [ { type:'input', field:'goods_name', title:'商品名称' }, { type:'datePicker', field:'created_at', title:'创建时间' } ], //组件参数配置 { el:root, //显示表单重置按钮 resetBtn:true, //表单提交事件 onSubmit:function (formData) { //按钮进入提交状态 $f.btn.loading(); } });
使用 JSON 生成表单
<div id="app3"> <div id="form-create"></div> </div> //JSON 规则 const rule = [ {"type":"input","field":"goods_name","title":"商品名称","value":"mi"}, {"type":"inputNumber","field":"goods_price","title":"商品价格","value":12} ] //表单插入的节点 const root = document.getElementById('form-create'); //$f为表单api const $f = window.formCreate.create( //表单生成规则 rule, //组件参数配置 { el:root, //显示表单重置按钮 resetBtn:true, //表单提交事件 onSubmit:function (formData) { //按钮进入提交状态 $f.btn.loading(); } });
以下是 from-create 的功能演示和参考案例
Vue.use(formCreate);
//Vue 组件
{
components: {
formCreate: formCreate.$form()
}
}
通过 form-create 生成的组件需要先通过以下方式挂载后才可以生成. 必须在挂载 formCreate 之前挂载所有需要生成的自定义组件
//自定义组件
Vue.component(TestComponent);
//或者
formCreate.component(TestComponent.name, TestComponent);
Vue.use(formCreate);
//自定义组件
formCreate.component(TestComponent.name, TestComponent);
//Vue 组件
{
components: {
formCreate: formCreate.$form()
}
}
例如给i-input组件添加on-change事件,事件名称参考Input
{
type:'input',
field: 'test',
title: 'test',
value: '',
on: {
'on-change': function(){
console.log('value 发生变化');
}
}
}
只支持在组件模式下
//rule
[{
type:'input',
field: 'test',
title: 'test',
value: '',
emit: ['on-change']
}]
事件名称为$ {field}-${eventName}
<form-create :rule="rule" test-on-change="onChange"> </form-create>
//rule
[{
type:'input',
field: 'test',
title: 'test',
value: '',
emit: ['on-change'],
emitPrefix: 'xaboy',
}]
事件名称为$ {emitPrefix}-${eventName}
<form-create :rule="rule" xaboy-on-change="onChange"> </form-create>
//rule
[{
type:'input',
field: 'test',
title: 'test',
value: '',
emit: ['on-change'],
emitPrefix: 'xaboy',
}]
$f.on('xaboy-on-change',function(){
//TODO
})
//rule
[{
type:'input',
field: 'test',
title: 'test',
value: '',
emit: [{
name: 'on-change',
inject: ['自定义参数,数据类型不限']
}],
emitPrefix: 'xaboy',
}]
<form-create :rule="rule" xaboy-on-change="onChange"> </form-create>
向事件中注入参数后,事件会额外增加一个参数
//未注入
{
onChange: function(val){
}
}
//注入后
{
onChange: function(inject, val){
}
}
inject 参数的数据结构
{
$f:Object,//api
rule:Array,//生成规则
self:Object,//当前生成规则
option:Object,//全局配置
inject:Any,//自定义注入的参数
}
参数注入也可以通过全局配置项injectEvent:true开启
通过设置生成规则的col配置项可以实现组件的布局
示例1:
[ { type:'input', field:'test-1', title:'col-12', value:'', col:{ span:12 } }, { type:'input', field:'test-2', title:'col-12', value:'', col:{ span:12 } } ]
示例2:
示例中使用的是 ElementU
I
当没有设置col时默认为{span:24}
[ { type: 'el-row', native: true, children: [ { type: 'el-col', props: { span: 12 }, children: [ { type:'datePicker', title: '活动日期', field: 'section_day', value: ['2018-02-20 12:12:12', '2018-03-20 12:12:12'], props:{ type:'datetimerange' } }, { type:'timePicker', title: '活动时间', field: 'section_time', value: ['11:11:11', '22:22:22'], props:{ isRange: true, placeholder: "请选择活动时间" } }, ] }, { type: 'el-col', props: { span: 12 }, children: [ { type:'inputNumber', title: '排序', field: 'sort', value: 0, props:{ precision: 2 }, col:{ span: 12 }, validate: [{require: true, type: 'number', min: 10}] }, { type:'colorPicker', title: '颜色', field: 'color', value: '#ff7271', props:{ hue: true, format: 'hex' }, col:{ span: 12 } }, ] } ] } ]
可以通过 validate 配置项设置组件的验证规则,自定义的表单组件也支持校验
type 需要根据组件的 value 类型定义
验证 input 组件必填
{
type:'input',
//...
validate: [{type: 'string', required: true}]
}
验证 date 组件必填
{
type:'datePicker',
//...
validate: [{type: 'date', required: true}]
}
验证 checkbox 组件 最少选择三个
{
type:'checkbox',
//...
validate: [{type: 'array', required: true, min:3}]
}
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
enum | 枚举类型 | string | - |
len | 字段长度 | number | - |
max | 最大长度 | number | - |
message | 校验文案 | string | - |
min | 最小长度 | number | - |
pattern | 正则表达式校验 | RegExp | - |
required | 是否必选 | boolean | false |
transform | 校验钱转换字段值 | function(value) => transformedValue:any | - |
type | 内建校验类型 | string | ‘string’ |
validator | 自定义校验 | function(rule, value, callback) | - |
whitespace | 必选时,空格是否会被视为错误 | boolean | false |
更多高级用法可研究 async-validator。
本文将介绍如何使用自定义组件按钮代替默认按钮
首先通过设置全局配置隐藏默认的提交按钮和重置按钮
{
submitBtn: false,
resetBtn: false
}
示例中使用的是 ElementUI
[ { type: 'input', field: 'field-1', title: 'test', value: 'test submit', col: { span:6 } }, { type: 'el-button', on: { click: function(){ //TODO 提交表单 $f.submit(); //或者 $f.resetFields(); } }, col: { span:3, push: 1 }, children: ['submit'] } ]
通过全局配置中的global配置项可实现组件的公共配置,支持设置组件所有的配置项
{
global: {
'*': {
props: {
disabled: true
},
col: {
span: 6
}
}
}
}
{
global: {
upload: {
props: {
onSuccess: function(res, file){
file.url = res.data.url;
}
}
}
}
}
生成规则
rule = [{
type:'input',
field: 'test',
title: 'test',
value: '',
props: {
disabled: false
},
emit: ['on-change']
}]
rule[0].props.disabled = true;
rule[0].value = "update";
通过$ f修改
获取$f
//通过`field`获取生成规则
const rule = $f.getRule('test');
//修改方法通过同上
const $model = $f.model();
const rule = $model.test;
$f.updateRule('test',{
value: 'update',
props: {
disabled: true
}
});
修改指定组件
$f.setValue('test', "update");
批量修改
$f.setValue({
test: "update"
});
自定义组件如果需要通过$f的方法需要定义name或者field 字段,自定义表单组件使用field,其他自定义组件使用name
生成规则
rule = [{
type:'i-button',
name: 'btn',
props: {
disabled: false
},
children: ['test Button']
}]
rule[0].props.disabled = true;
通过$ f修改
获取$f
//通过field
获取生成规则
const rule = $f.getRule('btn');
//修改方法通过同上
const $component = $f.component();
const rule = $component.btn;
$f.updateRule('btn',{
props: {
disabled: true
}
});
rule.push({
type:"input",
title:"商品简介",
field:"goods_info",
value:"",
props: {
"type": "text",
"placeholder": "请输入商品简介",
},
validate:[
{ required: true, message: '请输入商品简介', trigger: 'blur' },
],
})
在 goods_name 字段后面增加一份图片上传组件,默认添加到尾部
$f.append({
type:"input",
title:"商品简介",
field:"goods_info",
value:"",
props: {
"type": "text",
"placeholder": "请输入商品简介",
},
validate:[
{ required: true, message: '请输入商品简介', trigger: 'blur' },
],
},'goods_name');
在 goods_name 字段之前增加一份 input 组件,默认添加到头部
$f.prepend({
type:"input",
title:"商品简介",
field:"goods_info",
value:"",
props: {
"type": "text",
"placeholder": "请输入商品简介",
},
validate:[
{ required: true, message: '请输入商品简介', trigger: 'blur' },
],
},'goods_name');
rule.splice(0,1);
$f.removeField('test');
$f.removeField('btn');
例如给i-input组件通过prefix和suffix设置前缀及后缀图标 Input
{ type:'input', field: 'test', title: 'test', value: '', children: [ { type:'i-con', props: { type: 'ios-contact' }, slot: 'prefix' //前置插槽的名称 }, { type:'i-con', props: { type: 'ios-search' }, slot: 'suffix' //后置插槽的名称 }, ] }
安装
npm install @form-create/data
导入
//省市二级联动
import province_city from "@form-create/data/dist/province_city.js"
//省市二级联动(id)
import province_city_code from "@form-create/data/dist/province_city_code.js"
//省市区三级联动
import province_city_area from "@form-create/data/dist/province_city_area.js"
//省市区三级联动(id)
import province_city_area_code from "@form-create/data/dist/province_city_area_code.js"
<!-- 省市二级联动 -->
<script src="https://cdn.jsdelivr.net/npm/@form-create/data/dist/province_city.js"></script>
<!-- 省市二级联动(id) -->
<script src="https://cdn.jsdelivr.net/npm/@form-create/data/dist/province_city_code.js"></script>
<!-- 省市区三级联动 -->
<script src="https://cdn.jsdelivr.net/npm/@form-create/data/dist/province_city_area.js"></script>
<!-- 省市区三级联动(id) -->
<script src="https://cdn.jsdelivr.net/npm/@form-create/data/dist/province_city_area_code.js"></script>
访问,以省市二级联动为例
formCreate.data.province_city
//或者
window.province_city
$f为创建表单后返回的实例,field 为字段名称,rule 为表单生成规则
说明: 如果修改的值为数组必须直接赋值或使用push,splice等方法修改
$f.setValue({[field1]:value1,[field2]:value2})
$f.model()[field].props.disabled = false
rule[2].props.disabled = false //rule[2]是要修改的生成规则
说明: 修改的属性需要提前在生成规则里预定义
在 goods_name 字段后面增加一份图片上传组件,默认添加到尾部
$f.append($formCreate.maker.upload( '产品主图', 'logo', 'http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg' ).props({ "action": "", "maxLength": 1, "multiple": false, "type": "select", "uploadType": "image", "name": "file", "onSuccess": function () { return 'http://img1.touxiang.cn/uploads/20131030/30-075657_191.jpg'; } }) .validate({required:true, type: 'array', min: 1, message: '请上传1张图片', trigger: 'change'} ),'goods_name');
在 goods_name 字段之前增加一份 input 组件,默认添加到头部
$f.prepend({
type:"input",
title:"商品简介",
field:"goods_info",
value:"",
props: {
"type": "text",
"placeholder": "请输入商品简介",
},
validate:[
{ required: true, message: '请输入商品简介', trigger: 'blur' },
],
},'goods_name');
在表单尾部追加一个 input 组件
rules.push({
type:"input",
title:"商品简介",
field:"goods_info",
value:"",
props: {
"type": "text",
"placeholder": "请输入商品简介",
},
validate:[
{ required: true, message: '请输入商品简介', trigger: 'blur' },
],
})
删除指定字段
$f.removeField(field);
删除最后一个字段
rules.pop()
$f.hidden(true, field)
fetch('api').then(rule=>{
$f = formCreate.create(rule,{
onSubmit(formData){
// 表单提交事件
$f.btn.loading(true);
//TODO 提交表单
}
})
})
设置全局配置options.submitBtn = false即可隐藏
option: {
submitBtn: {
type: "basic",
size: "mini",
icon: "",
shape: "round",
innerText: "submit",
col: {
span: 4,
offset: 10
}
}
}
设置全局配置options.resetBtn = true即可显示
获取 $f 参考
在配置项中调用外层组件的方法 参考 #51
规则正在其他form-create中使用
一个生成规则rule只能同时在一个中使用. 如果需要多次使用:
请注意 value 的数据类型.如果组件为多选或区间选择时 value 的数据类型为Array,需要在验证规则中设置type:‘array’
将 slot 配置项配置在 props 中
props: {
"trueValue":"1",
"falseValue":"0",
"slot": {
open:"上架",
close:"下架",
},
}
在表单创建后到成功渲染之前修改是无效的
———————————————
版权声明:本文为CSDN博主「星河子_YumWisdom」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Aria_Miazzy/article/details/103746336
<template> <div> <div ref="window_bl"> </div> <div id="dome"></div> </div> </template> <script> export default { data() { return { fc: null, message:'', }; }, mounted: function () { this.create(); }, methods: { create() { let rules = [ { type: "child", field: "child", title: "找子组件哇!", props: { title: "是子组件哇!", message: "找我干什么?", }, on: { destoryed: (param) => { let x; let cm = confirm('按下呼叫?'); if(cm == true){ x = '你是呼叫谁?' }else { x = "不了不了,再见!" } document.getElementById('dome').innerHTML = x; document.getElementById('dome').innerHTML += param.name +"~~~" + param.study; }, alert: (param) => { console.log(param); alert(param) }, }, }, ]; this.fc = this.$formCreate(rules, { el: this.$refs.window_bl, resetBtn: true, submitBtn: false, }); }, }, }; </script> <style> </style>
<template> <div> <h3>{{ title }}</h3> <div>{{ message }}</div> <div> <button @click="destoryed">关闭</button> <button @click="alert">提问</button> </div> </div> </template> <script> export default { methods: {}, props: { title: { type: String, default: "哈喽", }, message: { type: String, default: "我在这", }, }, methods: { destoryed() { let data = { name: "ll", study: "学习html", }; this.$emit("destoryed", data); }, alert() { this.$emit("alert", "你猜我现在想干嘛?"); }, }, }; </script> <style> button { width: 80px; height: 50px; border: none; font-size: 18px; background: #cccbcb; color: aquamarine; } </style>
子组件在使用之前需要先注册
可将以下代码添加到一个新建的文件下:我直接放在config-> index.js了
import child from '@/components/child';
Vue.component('child', child)
部分效果预览
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。