前端配置化表單組件設計方法

来源:https://www.cnblogs.com/Jcloud/archive/2023/05/06/17378240.html
-Advertisement-
Play Games

前端開發中涉及表單的頁面非常多,看似功能簡單,開發快速,實則占去了很大一部分時間。當某個表單包含元素過多時還會導致html代碼過多,vue文件過大。從而不容易查找、修改和維護。為了提高開發效率及降低維護成本,下麵介紹表單配置化組件的封裝原理與封裝方法。 ...


一、背景

前端開發中涉及表單的頁面非常多,看似功能簡單,開發快速,實則占去了很大一部分時間。當某個表單包含元素過多時還會導致html代碼過多,vue文件過大。從而不容易查找、修改和維護。為了提高開發效率及降低維護成本,下麵介紹表單配置化組件的封裝原理與封裝方法。

二、技術方案

如上圖所示,封裝表單配置化組件的關鍵點有三個一是如何解決表單元素排布的行列問題,二是表單數據的綁定問題,三是表單元素的參數配置校驗等問題。下麵分別介紹這三個問題的解決方法。

•配置化表單組件的入參及說明

參數 說明 類型 可選值 預設值
labelWidth 表單元素label所占寬度 String —— 150px
columnList 表單元素所組成的配置,是一個數組 Array —— []
formData 表單元素值的集合 Object —— {}
columnSpan 表單排布分欄 Number —— 24
size 表單元素尺寸 String medium / small / mini medium

•計算配置化表單的行數,本表單通過基礎的24分欄計算表單最終的行數和列數,通過下麵方法最終得到一個關於行列的二維數組

newColumnList() {
  const newColumnList= []
  const row = Math.floor(24 / this.columnSpan)
  let newColumnItem = []
  for(let i=0; i< this.columnList.length; i++) {
    newColumnItem.push(this.columnList[i])
    if(newColumnItem.length === row || i === this.columnList.length-1) {
      newColumnList.push(newColumnItem)
      newColumnItem = []
    }
  }
  return newColumnList
}

•通過上面得到的二維數組進行迴圈渲染,首先迴圈渲染行,其次迴圈渲染列。本方案採用element中的表單,當然也可以用其他組件庫或者原生表單進行渲染,其原理通用。最終將會根據參數column.type決定載入哪一個具體的表單元素。

<el-form ref="form" :model="formData" :label-width="labelWidth" :size="size">
    <el-row :gutter="20" v-for="(element,index) in newColumnList" :key="index+'formRow'">
      <template v-for="(item, index) in element" >
        <column
          :key="index + 'formView'"
          :columnSpan="columnSpan"
          :column="item"
          :formData="formData"
        />
      </template>
    </el-row>
</el-form>

•column組件最終根據type載入具體的表單元素。下麵展示column組件的入參及其說明,通過component載入不同的表單元素

參數 說明 類型 可選值 預設值
column 表單元素的具體配置 Object —— {}
formData 表單元素值的集合 Object —— {}
columnSpan 表單排布分欄 Number —— 24
<el-col :span="columnSpan">
     <component
      :is="column.type + 'View'"
      :column="column"
      :formData="formData"
      v-model="formData[column.name]"
      :columnSpan="columnSpan"/>
 </el-col>

•這裡主要以select表單元素為例進行說明,表單元素的雙向綁定、校驗以及值更新等問題

參數 說明 類型 可選值 預設值
column 表單元素的具體配置 Object —— {}
value 表單元素值 Number/String/Array —— ——

•column參數

參數 說明 類型 可選值 預設值
placeholder 空值說明 String —— ——
required 是否必填 Boolean —— ——
rules 校驗規則 Array —— ——
title 表單元素label String —— ——
name 表單元素值名稱 String —— ——
multiple 是否多選 Boolean —— ——
filterable 是否過濾 Boolean —— ——
disabled 是否禁用 Boolean —— ——
dictionary 下拉選項枚舉 Array —— ——
changeFunction 值改變時的回調函數 Function —— ——
<el-form-item :label="column.title + ':'" :prop="column.name" :rules="rules">
    <el-select
      v-model="val"
      clearable
      :multiple="column.multiple"
      :filterable="column.filterable"
      :placeholder="'請選擇' + column.title"
      :disabled="column.disabled"
      style="width: 100%"
      @change="onChange"
      @clear="onClear">
      <el-option v-for="item in column.dictionary" :key="item.code" :label="item.name" :value="item.code">
      </el-option>
    </el-select>
</el-form-item>

rules:  [
    {
      required: this.column.required,
      message: this.column.placeholder placeholder ? this.column.placeholder : `請輸入${this.column.title}`,
      trigger: 'change'
    },
    ...this.column.rules
 ]

onChange(){
  this.$emit('input',this.val)
  if(this.column && this.column.changeFunction){
    this.column.changeFunction(this.val)
  }
},
onClear(){
  this.onChange()
}

三、項目實踐

•配置化表單為bs-form,在頁面中引入bs-form表單組件

<bs-form ref="formDemo"
     :columnList="columnList"
     :formData="formData"
     :columnSpan="columnSpan"
     labelWidth="120px">
</bs-form>
<el-row style="text-align: center;">
  <el-button type="primary"
             @click="onSave">保存</el-button>
  <el-button @click="onCancel">取消</el-button>
</el-row>

•formData參數

formData: {
    name: '',
    yearIncome: '', // 業務類型
    goodsCategoryId: '', // 托寄物品類id
    projectManagerErp: '', // 項目經理erp
    projectName: '', // 項目名稱
    projectStage: '', // 項目階段編碼
    projectStandardName: '', // 標準名稱
    projectYear: 2023, // 年份
    startRegionId: '', // 始發區域id
    startBattleId: '', // 始發戰區id
    address: [], // 省市
    category: null, //圖文類型
    range: [] //發佈範圍
 }

•分欄參數

columnSpan: 6

•表單配置參數

columnList(){
  const self = this
  return [
    {
      type: 'text',
      name: 'name',
      title: '項目名稱',
      required: true,
      maxlength: 20,
      showwordlimit: true,
      placeholder: '請輸入'
    },
    {
      name: 'category',
      type: 'radio',
      dictionary: [
        {
          code: 1,
          name: '類型一'
        },
        {
          code: 2,
          name: '類型二'
        }
      ],
      title: '圖文類型',
      required: true
    },
    {
      name: 'range',
      type: 'checkbox',
      title: '發佈範圍',
      dictionary: [
        {
          code: 1,
          name: '範圍一'
        },
        {
          code: 2,
          name: '範圍二'
        }
      ],
      required: true
    },
    {
      type: 'text',  // 欄位類型文本框
      name: 'yearIncome',  //與後臺對接欄位
      title: '年均收入',  // 前端展示欄位
      required: true, // 必填項設置
      maxlength: 50,  // 字元串長度限制
      showwordlimit: true, // 是否顯示字元串長度
      placeholder: '請輸入', // 占位文本提示
      rules: [
        { pattern: /(^[1-9]([0-9]+)?(.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9].[0-9]([0-9])?$)/, message: '請輸入數字最多兩位小數' }
      ],
    },
    {
      type: 'select',
      name: 'goodsCategoryId',
      title: '托寄物品類',
      required: true,
      filterable: true,
      placeholder: '請選擇',
      dictionary: [{
        name: '蘋果',
        code: '1'
      },{
        name: '手機',
        code: '2'
      },{
        name: '測試',
        code: '3'
      },{
        name: '櫻桃',
        code: '7'
      },{
        name: '荸薺',
        code: '9'
      }]
    },
    {
      type: 'select',
      name: 'startRegionId',
      title: '區域',
      required: true,
      placeholder: '請選擇',
      dictionary: [{
        name: '銷售-華北區域',
        code: '1'
      },{
        name: '銷售-華東區域',
        code: '2'
      },{
        name: '銷售-華南區域',
        code: '3'
      },{
        name: '銷售-西南區域',
        code: '4'
      },{
        name: '銷售-華中區域',
        code: '5'
      },{
        name: '銷售-東北區域',
        code: '6'
      }],
      // 點擊下來觸發切換聯動的事件,為一個函數
      changeFunction: function (val) {
      }
    }, {
      type: 'select',
      name: 'startBattleId',
      title: '戰區',
      required: true,
      placeholder: '請選擇',
      dictionary: this.battleByRegionList
    }, {
      type: 'select',
      name: 'projectStage',
      title: '項目階段',
      required: true,
      placeholder: '請選擇',
      dictionary: [{
        name: '項目發起階段',
        code: '10'
      },{
        name: '項目調研階段',
        code: '20'
      },{
        name: '可行性分析階段',
        code: '30'
      },{
        name: '立項階段',
        code: '40'
      }]
    }, {
      type: 'text',
      name: 'projectStandardName',
      title: '標準名稱',
      required: true,
      placeholder: '請輸入',
      append: '.com',  // 文本框後置內容
    }, {
      type: 'text',
      name: 'projectManagerErp',
      title: '項目經理',
      required: true,
      placeholder: '請輸入'
    },{
      type: 'cascader',  // 欄位類型下拉框
      name: 'address',   //與後臺對接欄位
      title: '省市區',  // 前端展示欄位
      required: true, // 必填項設置
      placeholder:'請選擇',  // 占位文本提示
      dictionary: [{
        value: 'shanxi',
        label: '陝西省',
        children: [{
          value: 'xian',
          label: '西安市',
          children: [{
            value: 'yanta',
            label: '雁塔區'
          }, {
            value: 'beilin',
            label: '碑林區'
          }, {
            value: 'xincheng',
            label: '新城區'
          }, {
            value: 'weiyang',
            label: '未央區'
          }]
        }]
      }],
      // 點擊下來觸發切換聯動的事件,為一個函數
      changeFunction: function(){}
    },{
      type: 'static',
      name: 'projectYear',
      title: '年份'
    }
  ]
}

•表單保存

// 保存
async onSave() {
  const valid = await this.$refs.formDemo.onValidate()
  if(valid) {
    this.$message.success('校驗通過')
  }else {
    this.$message.error('校驗失敗')
  }
}

四、成果展示

作者:京東物流 田雷雷


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 藉助於 mysqldump 命令可以進行資料庫的備份。 用法: mysqldump [OPTIONS] database [tables] 或:mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] 或:mysqldump [OPTION ...
  • 本文分享自天翼雲開發者社區《如何計算真實的資料庫成本》 作者:王****乾 在雲計算占主導地位之前,計算資料庫的成本是一個非常簡單的等式:軟體成本+硬體成本=資料庫成本。如果你選擇了一個開源產品,軟體成本可能會消失。雖然雲計算已經從根本上改變了我們使用和部署軟體的方式,但仍有太多人在使用這種過時的計 ...
  • 在之前的內容當中,我們為大家介紹過 ChengYing 的安裝原理、產品包製作等內容,本篇就延續之前的內容,和大家展開聊聊 ChengYing 產品線部署相關的設計。幫助對「一站式全自動化全生命周期大數據平臺運維管家 ChengYing」感興趣的開發者更好地瞭解和使用 ChengYing。 產品線部 ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 文章來源:GreatSQL社區原創 線上使用MySQL8.0.25的資料庫,通過監控發現資料庫在查詢一個視圖(80張表的union all)時記憶體和cp ...
  • 前言 從今天開始本系列文內容就帶各位小伙伴學習資料庫技術。資料庫技術是Java開發中必不可少的一部分知識內容。也是非常重要的技術。本系列教程由淺入深, 全面講解資料庫體系。 非常適合零基礎的小伙伴來學習。 全文大約 【1066】字,不說廢話,只講可以讓你學到技術、明白原理的純乾貨!本文帶有豐富案例及 ...
  • 提起分庫分表,對於大部分伺服器開發來說,其實並不是一個新鮮的名詞。隨著業務的發展,我們表中的數據量會變的越來越大,欄位也可能隨著業務複雜度的升高而逐漸增多,我們為瞭解決單表的查詢性能問題,一般會進行分表操作。 同時我們業務的用戶活躍度也會越來越高,併發量級不斷加大,那麼可能會達到單個資料庫的處理能... ...
  • 分析服務 ◆ 事件分析下新增商品訂閱分析報告,幫助開發者瞭解應用內用戶付費訂閱概況,評估訂閱付費價值; ◆ 營銷分析、用戶質量、轉化分析以及過濾器中,新增廣告系列/廣告任務通過ID進行搜索的功能,通過更便捷高效的數據分析體驗,幫助開發者合理評估廣告投放的後端轉化效果。 查看詳情>> 運動健康服務 ◆ ...
  • 在Flutter中,我們有各種插件可供使用,從而實現音頻和視頻的播放功能。 例如,可以使用“text_to_speech”插件來將文字轉換為語音,使用內置的“video_player”插件輕鬆地實現視頻播放,或者使用“audioplayers”插件實現音頻播放。 對於僅需要簡單播放器功能的情況,也可 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...