号外号外!唯品会第一个前端开源项目来啦,就是它 - ncform
官方github:https://github.com/vipshop/ncform
好了,广告打好了,今天,我来给大家讲个故事,故事名叫华山论“单”。此处应该有掌声,好了,Let's go:
佩之和赋占各自修炼多年后,相约华山比试修炼成果
人物介绍:
佩之,擅长配置,拥有高超的将具象抽象成配置的能力;
赋占,手速飞快,毫秒级完成复制粘贴, 人称闪电手;
此次的比试主题,就是(长期占据后台管理系统的C位)表单的开发效率
第一回合,最基本的表单+验证
只见赋占摩拳擦掌,哨声一响,以飞快的速度在element-ui的官方文档和代码编辑器之间来回切换,复制粘贴控件的代码,哒哒哒哒哒~~~
立即创建
{
data: {
ruleForm: {
name: '',
region: '',
type: [],
resource: '',
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
region: [
{ required: true, message: '请选择活动区域', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
],
resource: [
{ required: true, message: '请选择活动资源', trigger: 'change' }
],
}
}
}
源码在此>>>
此时,旁边的佩之微微一笑,淡定的丢出了一份配置
{
type: 'object',
properties: {
name: {
type: 'string',
ui: {
label: '活动名称'
},
rules: {
required: {
value: true,
errMsg: '请输入活动名称'
},
minLength: {
value: 3,
errMsg: '长度在 3 到 5 个字符'
},
maxLength: {
value: 5,
errMsg: '长度在 3 到 5 个字符'
}
}
},
region: {
type: 'string',
ui: {
label: '活动区域',
placeholder: '请选择活动区域',
widget: 'select',
widgetConfig: {
enumSource: [
{
value: 'shanghai',
label: '区域一'
},
{
value: 'beijing',
label: '区域二'
}
]
}
},
rules: {
required: {
value: true,
errMsg: '请选择活动区域'
}
}
},
type: {
type: 'array',
ui: {
label: '活动性质',
widget: 'checkbox',
widgetConfig: {
enumSource: [
{
value: '美食/餐厅线上活动',
label: '美食/餐厅线上活动'
},
{
value: '地推活动',
label: '地推活动'
}
]
}
},
rules: {
required: {
value: true,
errMsg: '请至少选择一个活动性质'
}
}
},
resource: {
type: 'string',
ui: {
label: '特殊资源',
widget: 'radio',
widgetConfig: {
enumSource: [
{
value: '线上品牌商赞助',
label: '线上品牌商赞助'
},
{
value: '线下场地免费',
label: '线下场地免费'
}
]
}
},
rules: {
required: {
value: true,
errMsg: '请选择活动资源'
}
}
}
}
}
源码在此>>>
赋占瞄了一眼,什么鬼,居然就一份配置就搞定了。
“似曾相识啊,不过这局这么简单,接下来复杂的你肯定搞不定,我就在接下来的回合KO掉你”
第二回合,城市选择器
赋占暗自窃喜了一下,这种组件之间有数据依赖的,我看你怎么破,然后又开始飞快地敲起键盘
{
created() {
this.getProvince();
},
data: {
form: {
province: '',
city: '',
},
provinceList: [],
cityList: []
},
methods: {
getProvince() {
axios.get('http://daniel.org/api/test/getProvinces').then(res => {
this.provinceList = res.data;
})
},
getCities() {
this.form.city = '';
axios.get('http://daniel.org/api/test/getCities', {
params: {
provinceId: this.form.province
}
}).then(res => {
this.cityList = res.data;
})
},
}
}
源码在引>>>
此时,佩之神情淡定,挥手又甩出了一份配置,一下子又搞定了
{
"type": "object",
"properties": {
"province": {
"type": "string",
"ui": {
"label": "省份",
"widget": "select",
"widgetConfig": {
"itemLabelField": "name",
"itemValueField": "id",
"enumSourceRemote": {
"remoteUrl": "http://daniel.org/api/test/getProvinces"
}
}
}
},
"city": {
"type": "string",
"ui": {
"label": "城市",
"widget": "select",
"widgetConfig": {
"itemLabelField": "name",
"itemValueField": "id",
"enumSourceRemote": {
"remoteUrl": "http://daniel.org/api/test/getCities"
"otherParams": {
"provinceId": "dx: {{$root.province}}"
}
}
}
}
}
}
源码在此>>>
赋占心里直郁闷:“我去,这都可以”
第三回合,日期比较+验证
赋占心想:“这个的难点在于操作开始日期的值,要触发结束日期的校验,有点隔空操作的意思,看你怎么配出来”,自个又开始了飞快的哒哒哒哒哒~~~
{
data() {
let validateStartTime = (rule, value, callback) => {
if (value === '') {
if (this.ruleForm.endTime) this.$refs.ruleForm.validateField('endTime');
callback();
} else {
if (this.ruleForm.endTime && this.ruleForm.endTime < value) {
callback(new Error('开始日期必须小于结束日期!'));
} else {
if (this.ruleForm.endTime) this.$refs.ruleForm.validateField('endTime');
}
}
};
let validateEndTime = (rule, value, callback) => {
if (value === '') {
if (this.ruleForm.startTime) this.$refs.ruleForm.validateField('startTime');
callback();
} else {
if (this.ruleForm.startTime && this.ruleForm.startTime > value) {
callback(new Error('结束日期必须大于结束日期!'));
} else {
if (this.ruleForm.startTime) this.$refs.ruleForm.validateField('startTime');
}
}
};
return {
ruleForm: {
startTime: 0,
endTime: 0
},
rules: {
startTime: [
{ validator: validateStartTime, trigger: 'change' }
],
endTime: [
{ validator: validateEndTime, trigger: 'change' }
]
}
}
}
}
源码在此>>>
佩之微微皱了眉头,思考了一下,手一挥,又一份配置飞了出来
{
"type": "object",
"properties": {
"startTime": {
"type": "string",
"ui": {
"widget": "date-picker"
},
"rules": {
"customRule": [
{
"script": "dx: !{{$root.endTime}} || {{$root.endTime}} >= {{$root.startTime}}",
"errMsg": "开始日期必须小于等于结束日期",
"linkItems": [
{
"fieldPath": "endTime",
"customRuleIdx": 0
}
]
}
]
}
},
"endTime": {
"type": "string",
"ui": {
"widget": "date-picker"
},
"rules": {
"customRule": [
{
"script": "dx: !{{$root.startTime}} || {{$root.endTime}} >= {{$root.startTime}}",
"errMsg": "结束日期必须大于等于开始日期",
"linkItems": [
{
"fieldPath": "startTime",
"customRuleIdx": 0
}
]
}
]
}
}
}
}
源码在此>>>
赋占终于沉不住气了,“我去,你这个是什么东西啊,啥都可以配配配”
佩之悠然地挥动着手上的扇子:“这就是表单开发利器-ncform”
【广告时间】
ncform,一种令人愉悦的表单开发方式,仅需配置即可生成表单UI及其交互行为。
用了它,更规范;用了它,更稳定; 用了它,更高效;用了它,更幸福;
而传统手工开发的表单,千人千种写法,可谓百家争鸣,而维护者痛苦不堪啊!