vue項目中動態生成form表單

在項目中經常遇到動態生成表單的需求,這次打算記錄下來。在我的這次項目(vue+element)中,有這樣一個需求。類似於 (a || b && c) || ((a || b) && c) && (a || b) 這樣的表達式,動態生成且和或組成的邏輯關係。具體的還是看圖吧

綠色框是一個大組,裏面可以無限地添加或和且關係的表達式。粉色框是一個小組,裏面是一個form表單,也是指一組表達式。選擇綠色框裏的 "請選擇邏輯條件"下拉框,下拉數據是 "且" 和 "或",然後點擊添加,這時候是在大組裏面添加一個小組,即添加了一個粉色框裏的內容。選擇黃色框裏的下拉框,點擊添加,添加的是一個大組。第二個綠色框就是選擇了黃色框裏的"或"條件添加的。點擊小組內的"刪除"按鈕,就是將粉色框裏的內容刪除,點擊"刪除所有條件"按鈕就是將整個大組刪除,即刪除綠色框的內容。大概的操作就是這樣的,裏面的業務我就不介紹了。在這裏只介紹一下動態生成表單,接下來就是碼代碼的時候了。

      <template v-if="conditionGroupList.length !== 0">
        <div v-for="(item, index) in conditionGroupList"
              :key="index">

          <el-row>
            <el-col 
              :span="24" 
              v-if="item.groupParamLogical === 'PARAM_LOGICAL_OR' &&
              index !== 0" 
              class="conditions_padding">或</el-col>
            <el-col 
              :span="24" 
              v-if="item.groupParamLogical === 'PARAM_LOGICAL_AND' &&
              index !== 0" 
              class="conditions_padding">且</el-col>
          </el-row>
          
          <el-form label-position="right" 
                    label-width="100px"
                    class="group"
                    :model="item">
            <el-row
              class="right"
              v-for="(itemLevel,index) in item.conditionList" 
              :key="index">
              <el-col 
                :span="24" 
                v-if="itemLevel.paramLogical === 'PARAM_LOGICAL_OR' &&
                index !== 0" 
                class="conditions_padding">或</el-col>
              <el-col 
                :span="24" 
                v-if="itemLevel.paramLogical === 'PARAM_LOGICAL_AND' &&
                index !== 0"
                class="conditions_padding">且</el-col>
              <el-col :span="8" class="conditionsStyle">
                <el-form-item label="表單">
                  <el-select v-model="itemLevel.formId"
                              @change="selectFormNode(itemLevel)"
                              clearable
                              placeholder="請選擇">
                    <el-option v-for="item in formNodeList"
                              :key="item.id"
                              :label="item.name"
                              :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8" class="conditionsStyle">
                <el-form-item label="屬性">
                  <el-select v-model="itemLevel.conditonKey"
                              clearable
                              placeholder="請選擇">
                    <el-option v-for="item in itemLevel.formTypeList"
                                :key="item.id"
                                :label="item.title"
                                :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8" class="conditionsStyle">
                <el-form-item label="條件">
                  <el-select v-model="itemLevel.paramCompare"
                            clearable
                            placeholder="請選擇">
                    <el-option v-for="item in conditionsList"
                              :key="item.id"
                              :label="item.name"
                              :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8" class="conditionsStyle">
                <el-form-item label="參數類型" label-width="100px">
                  <el-select v-model="itemLevel.paramType"
                              clearable
                              @change="selectParamType(itemLevel)"
                              placeholder="請選擇">
                    <el-option v-for="item in paramTypeList"
                                :key="item.id"
                                :label="item.name"
                                :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8" class="conditionsStyle">
                <el-form-item v-if="itemLevel.paramType === 'PARAM_TYPE_DATE'" label="值" label-width="100px">
                  <el-date-picker
                    v-model="itemLevel.conditionValue"
                    type="date"
                    value-format="yyyy-MM-dd"
                    placeholder="選擇日期">
                  </el-date-picker>
                </el-form-item>
                <el-form-item v-else label="值" label-width="100px">
                  <el-input v-model="itemLevel.conditionValue"></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="4"
                      class="conditionsStyle">
                <el-button type="danger"
                          @click="deleteConditions(item, index)">
                  刪除
                </el-button>
              </el-col>
            </el-row>
          </el-form>
          <el-row class="group">
            <el-col :span="5"
                    class="conditionsStyle bottom">
              <el-select v-model="item.selectParamLogicalButton"
                        clearable
                        placeholder="請選擇邏輯條件">
                <el-option label="且條件"
                          value="PARAM_LOGICAL_AND"></el-option>
                <el-option label="或條件"
                          value="PARAM_LOGICAL_OR"></el-option>
              </el-select>
            </el-col>
            <el-col :span="4"
                    class="conditionsStyle bottom">
              <el-button @click="addConditions(index)"
                        type="primary">添加</el-button>
            </el-col>
            <el-col 
              :span="4"     
              class="conditionsStyle bottom">
              <el-button
                @click="deleteAllConditions(index)"
                v-if="conditionGroupList.length > 1 && item.conditionList.length !== 0"
                type="danger">刪除所有條件</el-button>
            </el-col>
          </el-row>
        </div>      
      </template> 

      <el-row>
        <el-col :span="5"
                class="conditionsStyle bottom">
          <el-select v-model="groupParamLogical"
                    clearable
                    placeholder="請選擇邏輯條件">
            <el-option label="且條件"
                      value="PARAM_LOGICAL_AND"></el-option>
            <el-option label="或條件"
                      value="PARAM_LOGICAL_OR"></el-option>
          </el-select>
        </el-col>
        <el-col :span="4"
                class="conditionsStyle bottom">
          <el-button @click="addOrConditions"
                    type="primary">添加</el-button>
        </el-col>
      </el-row>

這是HTML部分的代碼,下面是在data中定義的數據

conditionGroupList: [
        {
          groupKey: 1,
          groupParamLogical: "PARAM_LOGICAL_AND",
          isFirstGroup: true,
          conditionList: [{
            conditonKey: "",
            // 屬性下拉數據
            formTypeList: [],
            formId: "",
            paramType: "",
            paramCompare: "",
            conditionValue: null,
            // 條件邏輯運算符
            paramLogical: "PARAM_LOGICAL_AND",
            isFirstParam: true
          }],
          // 組內(綠色框內)邏輯運算按鈕 
          // (定義這個變量是爲了防止新增條件組時,組內的邏輯選擇框被賦值爲添加組邏輯條件的值)
          selectParamLogicalButton: ""
        }
      ],

      // 組外(黃色框)的邏輯運算 或 且的值
      groupParamLogical: "",

html代碼和數據對應起來就知道里面綁定的數據的意義了,我就不囉嗦啦。接下來是添加和刪除的方法,寫在methods裏面。

// 添加一個大組的方法
    addOrConditions() {
      if (this.groupParamLogical) {
        this.conditionGroupList.push({
          groupKey: this.conditionGroupList.length === 0 ? 1 : ++this.afterKey,
          conditionList: [{
            conditonKey: "",
            formTypeList: [],
            formId: "",
            paramType: "",
            paramCompare: "",
            conditionValue: null,
            // 條件邏輯運算符
            paramLogical: "PARAM_LOGICAL_AND",
            isFirstParam: true
          }],
          groupParamLogical: this.groupParamLogical,
          isFirstGroup: this.conditionGroupList.length === 0 ? true : false
        });
        this.groupParamLogical = "";
      } else {
        this.$message.warning("請先選擇邏輯條件");
      }
    },


// 刪除一個大組的所有條件
    deleteAllConditions(index) {
      this.conditionGroupList.splice(index, 1);
    },


// 新增一個小組
   addConditions(index) {
      if (this.conditionGroupList[index].selectParamLogicalButton) {
        this.conditionGroupList[index].conditionList.push({
          conditonKey: "",
          formTypeList: [],
          formId: "",
          paramType: "",
          paramCompare: "",
          conditionValue: null,
          paramLogical: this.conditionGroupList[index].selectParamLogicalButton,
          isFirstParam: this.conditionGroupList[index].conditionList.length === 0 ? true : false
        });
        this.conditionGroupList[index].selectParamLogicalButton = "";
      } else {
        this.$message.warning("請先選擇邏輯條件");
      }
    },


//  刪除一個小組
    deleteConditions(item, index) {
      item.conditionList.splice(index, 1);

      // 如果刪除小組條件後,這個大組沒有條件了,那麼這個大組也要刪除掉
      if (item.conditionList.length === 0) {
        this.conditionGroupList.forEach((v, i) => {
          if (item.groupKey === v.groupKey) {
            this.conditionGroupList.splice(i, 1);
          }
        });
      }
    }

最後,再見啦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章