號外號外疮跑!唯品會第一個前端開源項目來啦谓形,就是它 - ncform
官方github:https://github.com/vipshop/ncform
好了然走,廣告打好了乍狐,今天弄企,我來給大家講個故事超燃,故事名叫華山論“單”。此處應(yīng)該有掌聲拘领,好了意乓,Let's go:
佩之和賦占各自修煉多年后,相約華山比試修煉成果
人物介紹:
佩之约素,擅長配置届良,擁有高超的將具象抽象成配置的能力笆凌;
賦占,手速飛快伙窃,毫秒級完成復(fù)制粘貼菩颖, 人稱閃電手;
此次的比試主題为障,就是(長期占據(jù)后臺管理系統(tǒng)的C位)表單的開發(fā)效率
第一回合晦闰,最基本的表單+驗(yàn)證
只見賦占摩拳擦掌,哨聲一響鳍怨,以飛快的速度在element-ui的官方文檔和代碼編輯器之間來回切換呻右,復(fù)制粘貼控件的代碼,噠噠噠噠噠~~~
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="活動名稱" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="活動區(qū)域" prop="region">
<el-select v-model="ruleForm.region" placeholder="請選擇活動區(qū)域">
<el-option label="區(qū)域一" value="shanghai"></el-option>
<el-option label="區(qū)域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活動性質(zhì)" prop="type">
<el-checkbox-group v-model="ruleForm.type">
<el-checkbox label="美食/餐廳線上活動" name="type"></el-checkbox>
<el-checkbox label="地推活動" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊資源" prop="resource">
<el-radio-group v-model="ruleForm.resource">
<el-radio label="線上品牌商贊助"></el-radio>
<el-radio label="線下場地免費(fèi)"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">立即創(chuàng)建</el-button>
</el-form-item>
</el-form>
{
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: '請選擇活動區(qū)域', trigger: 'change' }
],
type: [
{ type: 'array', required: true, message: '請至少選擇一個活動性質(zhì)', 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: '活動區(qū)域',
placeholder: '請選擇活動區(qū)域',
widget: 'select',
widgetConfig: {
enumSource: [
{
value: 'shanghai',
label: '區(qū)域一'
},
{
value: 'beijing',
label: '區(qū)域二'
}
]
}
},
rules: {
required: {
value: true,
errMsg: '請選擇活動區(qū)域'
}
}
},
type: {
type: 'array',
ui: {
label: '活動性質(zhì)',
widget: 'checkbox',
widgetConfig: {
enumSource: [
{
value: '美食/餐廳線上活動',
label: '美食/餐廳線上活動'
},
{
value: '地推活動',
label: '地推活動'
}
]
}
},
rules: {
required: {
value: true,
errMsg: '請至少選擇一個活動性質(zhì)'
}
}
},
resource: {
type: 'string',
ui: {
label: '特殊資源',
widget: 'radio',
widgetConfig: {
enumSource: [
{
value: '線上品牌商贊助',
label: '線上品牌商贊助'
},
{
value: '線下場地免費(fèi)',
label: '線下場地免費(fèi)'
}
]
}
},
rules: {
required: {
value: true,
errMsg: '請選擇活動資源'
}
}
}
}
}
賦占瞄了一眼,什么鬼侦香,居然就一份配置就搞定了落塑。
“似曾相識啊,不過這局這么簡單罐韩,接下來復(fù)雜的你肯定搞不定憾赁,我就在接下來的回合KO掉你”
第二回合,城市選擇器
賦占暗自竊喜了一下散吵,這種組件之間有數(shù)據(jù)依賴的龙考,我看你怎么破,然后又開始飛快地敲起鍵盤
<el-form :model="form" label-width="100px" class="demo-form">
<el-form-item label="省份" prop="province">
<el-select v-model="form.province" @change="getCities" placeholder="請選擇">
<el-option v-for="item in provinceList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="城市" prop="city">
<el-select v-model="form.city" placeholder="請選擇">
<el-option v-for="item in cityList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
{
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}}"
}
}
}
}
}
}
賦占心里直郁悶:“我去枚冗,這都可以”
第三回合缓溅,日期比較+驗(yàn)證
賦占心想:“這個的難點(diǎn)在于操作開始日期的值,要觸發(fā)結(jié)束日期的校驗(yàn)官紫,有點(diǎn)隔空操作的意思肛宋,看你怎么配出來”,自個又開始了飛快的噠噠噠噠噠~~~
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="startTime" prop="startTime">
<el-date-picker
v-model="ruleForm.startTime"
value-format="timestamp"
type="date"
placeholder="選擇日期">
</el-date-picker>
</el-form-item>
<el-form-item label="endTime" prop="endTime">
<el-date-picker
v-model="ruleForm.endTime"
value-format="timestamp"
type="date"
placeholder="選擇日期">
</el-date-picker>
</el-form-item>
</el-form>
{
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('開始日期必須小于結(jié)束日期!'));
} 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('結(jié)束日期必須大于結(jié)束日期!'));
} 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": "開始日期必須小于等于結(jié)束日期",
"linkItems": [
{
"fieldPath": "endTime",
"customRuleIdx": 0
}
]
}
]
}
},
"endTime": {
"type": "string",
"ui": {
"widget": "date-picker"
},
"rules": {
"customRule": [
{
"script": "dx: !{{$root.startTime}} || {{$root.endTime}} >= {{$root.startTime}}",
"errMsg": "結(jié)束日期必須大于等于開始日期",
"linkItems": [
{
"fieldPath": "startTime",
"customRuleIdx": 0
}
]
}
]
}
}
}
}
賦占終于沉不住氣了毁涉,“我去沉帮,你這個是什么東西啊,啥都可以配配配”
佩之悠然地?fù)]動著手上的扇子:“這就是表單開發(fā)利器-ncform”
【廣告時間】
ncform,一種令人愉悅的表單開發(fā)方式穆壕,僅需配置即可生成表單UI及其交互行為待牵。
用了它,更規(guī)范喇勋;用了它缨该,更穩(wěn)定; 用了它川背,更高效贰拿;用了它,更幸福熄云;
而傳統(tǒng)手工開發(fā)的表單膨更,千人千種寫法,可謂百家爭鳴缴允,而維護(hù)者痛苦不堪凹允亍!