華山論“單”

配置開發(fā)

號外號外疮跑!唯品會第一個前端開源項目來啦谓形,就是它 - 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ù)者痛苦不堪凹允亍!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末练般,一起剝皮案震驚了整個濱河市矗漾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌薄料,老刑警劉巖缩功,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異都办,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)虑稼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門琳钉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛛倦,你說我怎么就攤上這事歌懒。” “怎么了溯壶?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵及皂,是天一觀的道長。 經(jīng)常有香客問我且改,道長验烧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任又跛,我火速辦了婚禮碍拆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己感混,他們只是感情好端幼,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弧满,像睡著了一般婆跑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上庭呜,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天滑进,我揣著相機(jī)與錄音,去河邊找鬼疟赊。 笑死郊供,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的近哟。 我是一名探鬼主播驮审,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吉执!你這毒婦竟也來了疯淫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戳玫,失蹤者是張志新(化名)和其女友劉穎熙掺,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咕宿,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡币绩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了府阀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缆镣。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖试浙,靈堂內(nèi)的尸體忽然破棺而出董瞻,到底是詐尸還是另有隱情,我是刑警寧澤田巴,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布钠糊,位于F島的核電站,受9級特大地震影響壹哺,放射性物質(zhì)發(fā)生泄漏抄伍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一管宵、第九天 我趴在偏房一處隱蔽的房頂上張望逝慧。 院中可真熱鬧昔脯,春花似錦、人聲如沸笛臣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沈堡。三九已至静陈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诞丽,已是汗流浹背鲸拥。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僧免,地道東北人刑赶。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像懂衩,于是被迫代替她去往敵國和親撞叨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 引言 這卷書信是特別有意味的浊洞,因?yàn)檫@是保羅最后的一封信牵敷,是他在羅馬最后一次坐監(jiān)時寫的,那時他曉得自己離世已為期不遠(yuǎn)...
    biddon閱讀 1,949評論 0 0
  • 清晨法希,窗外微雨枷餐,窗外的雨聲一掃心中的喧囂情緒,雨滴拍打在窗玻璃上苫亦,猶如嬰兒的手指在敲打毛肋,又如少女的吻,清純而...
    謝茹妤閱讀 272評論 0 4
  • 前一段時間我看到這個流傳的圖片屋剑,意思是多么可愛的小朋友村生,你看到他明亮的眼睛么?我一開始以為是瞎子饼丘,遭受過暗黑的過去...
    五彩冰峰閱讀 427評論 3 0
  • 最難的是堅持 是堅持會讓你心安 還是會讓你不沮喪 多想去改變 可當(dāng)你覺得你已經(jīng)邁入正軌的時候 轉(zhuǎn)頭才發(fā)現(xiàn)你卻擺脫不...
    成小南閱讀 142評論 0 0