Vue3組件(九)封裝一個長大的表單(上)

一個神奇的表單

表單表單卜壕,你已經長大了您旁,你要學會自己:

  • 排成一列
  • 排成一行
  • 驗證表單數據
  • 排成方隊
  • 合并調整
  • 動態(tài)渲染
  • 支持 item 擴展組件
  • 可以自動創(chuàng)建 model

實現多行多列的表單

首先感謝 el-form,真的很強大轴捎,不僅好看鹤盒,還提供了驗證功能,還有很多其他的功能侦副。
只是好像只能橫著排侦锯,或者豎著排。那么能不能多行多列呢秦驯?似乎沒有直接提供尺碰。

我們知道 el-row、el-col 可以實現多行多列的功能译隘,那么能不能結合一下呢亲桥?官網也不直說,害的我各種找固耘,還好找到了题篷。(好吧,其實折騰了一陣著的table)

二者結合一下就可以了厅目,這里有個小技巧番枚,el-row只需要一個就可以,el-col可以有多個损敷,這樣一行排滿后葫笼,會自動排到下一行。

  <el-form ref="form" :model="formModule" label-width="130px">
      <el-row>
        <!--不循環(huán)row嗤锉,直接循環(huán)col渔欢,放不下會自動往下串行。-->
        <el-col :span="8">
           <!--假裝有好多好多的el-col-->
           <el-form-item :label="姓名:">
              <!--這里可以放組件-->
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

這樣有什么好處呢瘟忱?當然是便于我們做v-for呀奥额,給 el-col 加上 v-for 就好苫幢。

實現動態(tài)渲染功能

表單嘛,那么多字段一個一個做多麻煩垫挨,v-for 一下不香嗎韩肝?
前面封裝了那么多的組件,就是為了可以 v-for九榔。

首先準備一個json文件哀峻,里面放置需要的組件的屬性。


003表單的json.png

json比較長哲泊,我們還是看截圖吧剩蟀,直觀一些。

然后用 require 讀取進來切威,當然也可以用 axios 來讀取育特。

然后表單控件就可以用這些屬性做循環(huán)了。

另外還有幾個附帶功能:

  • 支持單行下的合并先朦。
    在單行的情況下缰冤,一些短的控件會比較占空間,我們可以把多個小的合并到一行喳魏。

  • 支持多行下的擴展棉浸。
    多行的情況下,一些長的控件需要占更多的空間刺彩,我們可以設置它多占幾個格子迷郑。

  • 自動創(chuàng)建表單需要的 model。
    不需要手動寫 model了迂苛。

自動創(chuàng)建 model

我比較懶三热,手擼 model 是不是有點麻煩?如果能夠自動獲得該多好三幻,于是我寫了這個函數就漾。

  // 創(chuàng)建 v-model
  const createModel = () => {
    // 依據meta,創(chuàng)建module
    for (const key in formItemMeta) {
      const m = formItemMeta[key]
      // 根據控件類型設置屬性值
      switch (m.controlType) {
        case 100: // 文本類
        case 101:
        case 102:
        case 103:
        case 104:
        case 105:
        case 106:
        case 107:
        case 130:
        case 131:
          formModel[m.colName] = ''
          break
        case 110: // 日期
        case 111: // 日期時間
        case 112: // 年月
        case 114: // 年
        case 113: // 年周
          formModel[m.colName] = null
          break
        case 115: // 任意時間
          formModel[m.colName] = '00:00:00'
          break
        case 116: // 選擇時間
          formModel[m.colName] = '00:00'
          break
        case 120: // 數字
        case 121:
          formModel[m.colName] = 0
          break
        case 150: // 勾選
        case 151: // 開關
          formModel[m.colName] = false
          break
        case 153: // 單選組
        case 160: // 下拉單選
        case 162: // 下拉聯(lián)動
          formModel[m.colName] = null
          break
        case 152: // 多選組
        case 161: // 下拉多選
          formModel[m.colName] = []
          break
      }
      // 看看有沒有設置默認值
      if (typeof m.defaultValue !== 'undefined') {
        switch (m.defaultValue) {
          case '':
            break
          case '{}':
            formModel[m.colName] = {}
            break
          case '[]':
            formModel[m.colName] = []
            break
          case 'date':
            formModel[m.colName] = new Date()
            break
          default:
            formModel[m.colName] = m.defaultValue
            break
        }
      }
    }
    // 同步父組件的v-model
    context.emit('update:modelValue', formModel)
  }

可以根據類型和默認值念搬,設置model的屬性抑堡,這樣就方便多了。

多列的表單

這個是最復雜的朗徊,分為兩種情況:單列的擠一擠首妖、多列的搶位置。

單列

單列的表單有一個特點爷恳,一行比較寬松有缆,那么有時候就需要兩個組件在一行里顯示,其他的還是一行一個組件,那么要如何調整呢棚壁?

這里做一個設定:

  • 一個組件一行的杯矩,記做1
  • 兩個組件擠一行的,記做-2
  • 三個組件擠一行的袖外,記做-3
    以此類推史隆,理論上最多支持-24,當然實際上似乎沒有這么寬的顯示器曼验。

這樣記錄之后泌射,我們就可以判斷,≥1的記做span=24鬓照,負數的熔酷,用24去除,得到的就是span的數字颖杏。當然記得取整數纯陨。

為啥用負數做標記呢?就是為了區(qū)分開多列的調整留储。

多列

多列的表單有一個特點,一個格子比較小咙轩,有些組件太長放不下获讳,這個時候這個組件就要搶后面的格子來用。

那么我們還是做一個設定:

  • 一個組件占一格的活喊,還是記做1
  • 一個組件占兩格的丐膝,記做2
  • 一個組件占三格的,記做3
    以此類推钾菊。

這樣記錄之后帅矗,我們可以判斷,≤1的煞烫,記做 24 / 列數浑此,大于1的記做 24/ 列數 * n。
這樣就可以了滞详,可以兼容單列的設置凛俱,不用因為單列變多列而調整設置。
只是有個小麻煩料饥,占得格子太多的話蒲犬,就會提取擠到下一行,而本行會出現“空缺”岸啡。
這個暫時靠人工調整吧原叮。
畢竟哪個字段在前面,還是需要人工設置的。

一頓分析猛如虎奋隶,一看代碼沒幾行擂送。

  // 調整行列
  const span = reactive({})
  // 根據配置里面的colCount,設置span
  const getSpan = () => {
    const formColCount = formMeta.formColCount // 列數
    const moreColSpan = 24 / formColCount // 一個格子占多少份

    if (formColCount === 1) {
    // 一列的情況
      for (const key in formItemMeta) {
        const m = formItemMeta[key]
        if (typeof m.colCount === 'undefined') {
          span[m.controlId] = moreColSpan
        } else {
          if (m.colCount >= 1) {
            // 單列达布,多占的也只有24格
            span[m.controlId] = moreColSpan
          } else if (m.colCount < 0) {
            // 擠一擠的情況团甲, 24 除以 占的份數
            span[m.controlId] = moreColSpan / (0 - m.colCount)
          }
        }
      }
    } else {
      // 多列的情況
      for (const key in formItemMeta) {
        const m = formItemMeta[key]
        if (typeof m.colCount === 'undefined') {
          span[m.controlId] = moreColSpan
        } else {
          if (m.colCount < 0 || m.colCount === 1) {
            // 多列,擠一擠的占一份
            span[m.controlId] = moreColSpan
          } else if (m.colCount > 1) {
            // 多列黍聂,占的格子數 * 份數
            span[m.controlId] = moreColSpan * m.colCount
          }
        }
      }
    }
  }

最后看看效果躺苦,可以動態(tài)設置列數:

動態(tài)表單001.gif

如果空間夠的話,最多可以是24列产还。應該是夠用了匹厘。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市脐区,隨后出現的幾起案子愈诚,更是在濱河造成了極大的恐慌,老刑警劉巖牛隅,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炕柔,死亡現場離奇詭異,居然都是意外死亡媒佣,警方通過查閱死者的電腦和手機匕累,發(fā)現死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來默伍,“玉大人欢嘿,你說我怎么就攤上這事∫埠” “怎么了炼蹦?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長狸剃。 經常有香客問我掐隐,道長,這世上最難降的妖魔是什么捕捂? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任瑟枫,我火速辦了婚禮,結果婚禮上指攒,老公的妹妹穿的比我還像新娘慷妙。我一直安慰自己,他們只是感情好允悦,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布膝擂。 她就那樣靜靜地躺著虑啤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪架馋。 梳的紋絲不亂的頭發(fā)上狞山,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音叉寂,去河邊找鬼萍启。 笑死,一個胖子當著我的面吹牛屏鳍,可吹牛的內容都是我干的勘纯。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼钓瞭,長吁一口氣:“原來是場噩夢啊……” “哼驳遵!你這毒婦竟也來了?” 一聲冷哼從身側響起山涡,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤堤结,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鸭丛,有當地人在樹林里發(fā)現了一具尸體竞穷,經...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年鳞溉,在試婚紗的時候發(fā)現自己被綠了来庭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡穿挨,死狀恐怖,靈堂內的尸體忽然破棺而出肴盏,到底是詐尸還是另有隱情科盛,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布蜜另,位于F島的核電站粥喜,受9級特大地震影響孵构,放射性物質發(fā)生泄漏。R本人自食惡果不足惜榨崩,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望章母。 院中可真熱鬧母蛛,春花似錦、人聲如沸乳怎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秫逝,卻和暖如春恕出,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背违帆。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工浙巫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刷后。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓的畴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惠险。 傳聞我的和親對象是個殘疾皇子苗傅,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容