element-ui form表单,内嵌表单数据校验

在最近开发的功能的过程中,遇到一个很复杂的表单;外层一个大表单;里面有一项是动态添加的,而且内嵌一个表单。每一项还有校验规则;如下图

记录一下调试结果。 无论多少层form, 注意几个事项;

form的model/ref;  form_item的prop这个关系到,校验作用具体那个框框 

数据还一个json,组件只是渲染UI,逐步分解就好了。

直接上完整代码,如下:

<!--定义巡检项-->
<template>
  <div class="drawer__content">
    <el-form :model="formUp" ref="formUp">
      <el-form-item
        label="巡检项名称"
        prop="name"
        :label-width="formLabelWidth"
        :rules="[
          { required: true, message: '请输入巡检项名称', trigger: 'blur' },
        ]"
      >
        <el-input
          v-model="formUp.name"
          autocomplete="off"
          maxlength="64"
        ></el-input>
      </el-form-item>
      <el-form-item
        label="巡检项描述"
        prop="description"
        :label-width="formLabelWidth"
        :rules="[
          { required: false, message: '请输入巡检项描述', trigger: 'blur' },
        ]"
      >
        <el-input
          v-model="formUp.description"
          type="textarea"
          autocomplete="off"
          maxlength="200"
          show-word-limit
        ></el-input>
      </el-form-item>
      <el-form-item
        label="巡检项登录用户"
        prop="itemLevels"
        :label-width="formLabelWidth"
        :rules="[
          {
            required: true,
            message: '请选择巡检项登录用户',
            trigger: 'change',
          },
        ]"
      >
        <el-checkbox-group v-model="formUp.itemLevels">
          <el-checkbox
            label="root"
            name="type"
            :disabled="formUp.itemLevels.includes('oracle')"
          ></el-checkbox>
          <el-checkbox
            label="administrator"
            name="type"
            class="borderRight"
            :disabled="formUp.itemLevels.includes('oracle')"
          ></el-checkbox>
          <el-checkbox
            label="oracle"
            name="type"
            :disabled="
              formUp.itemLevels.includes('root') ||
              formUp.itemLevels.includes('administrator')
            "
          ></el-checkbox>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item
        label="巡检项分类"
        prop="itemCategoryId"
        :label-width="formLabelWidth"
        :rules="[
          { required: false, message: '请选择巡检项分类', trigger: 'change' },
        ]"
      >
        <el-cascader
          v-model="formUp.itemCategoryId"
          clearable
          :filterable="true"
          :props="{
            value: 'id',
            label: 'name',
            children: 'children',
            emitPath: 'false',
            checkStrictly: true,
          }"
          :options="folderData"
          :show-all-levels="false"
        >
          <template slot-scope="{ node, data }">
            <span>{{ data.name }}</span>
          </template>
        </el-cascader>
      </el-form-item>
      <el-form-item
        label="资源分类"
        prop="resourceCateId"
        :label-width="formLabelWidth"
        :rules="[
          { required: true, message: '请选择资源分类', trigger: 'change' },
        ]"
      >
        <el-select
          v-model="formUp.resourceCateId"
          placeholder="请选择资源分类"
          @change="getTemplateArr"
          :disabled="setDialogType == 'edit'"
        >
          <el-option
            v-for="resourceItem in resourceArr"
            :key="resourceItem.id"
            :label="resourceItem.name"
            :value="resourceItem.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item
        label="结果判定"
        prop="resultCheck"
        :label-width="formLabelWidth"
      >
        <el-switch
          v-model="formUp.resultCheck"
          active-text="有"
          inactive-text="无"
        >
        </el-switch>
      </el-form-item>
      <el-form-item :label-width="formLabelWidth">
        <div slot="label">
          <span
            ><i style="color: #f56c6c; margin-right: 4px">*</i
            >能力模板及表达式配置</span
          >
        </div>
        <div class="addForm">
          <el-button
            type="primary"
            icon="el-icon-circle-plus"
            @click="addTemplate(formUp.templateConfigList)"
            >增加能力模板</el-button
          >
        </div>
        <div class="formContent">
          <div
            class="formItem"
            v-for="(itemForm, indexA) in formUp.templateConfigList"
            :key="indexA"
          >
            <h4>
              能力模板{{ indexA + 1 }}
              <i
                style="margin-left: 10px; font-size: 16px; cursor: pointer"
                class="el-icon-delete-solid"
                v-if="indexA > 0"
                @click="deleteTemplate(indexA)"
              ></i>
            </h4>
            <el-form :model="itemForm" :ref="'formDown' + indexA">
              <!-- 选择能力模板 -->
              <el-form-item
                label="选择能力模板"
                prop="abilityTemplateId"
                :label-width="formLabelWidthB"
                :rules="[
                  {
                    required: true,
                    message: '请选择能力模板',
                    trigger: 'change',
                  },
                ]"
              >
                <el-select
                  v-model="itemForm.abilityTemplateId"
                  placeholder="请选择能力模板"
                  @change="
                    changeItemTemplate(itemForm.abilityTemplateId, itemForm)
                  "
                >
                  <el-option
                    v-for="(a, index1) in powerArr"
                    :key="index1"
                    :label="a.name"
                    :value="a.id"
                  ></el-option>
                </el-select>
              </el-form-item>
              <!-- 数据库部署模式 -->
              <!-- <el-form-item
                v-if="formUp.resultCheck"
                label="数据库部署模式"
                prop="dbDeployType"
                :label-width="formLabelWidthB"
                :rules="[
                  {
                    required: false,
                    message: '请选择数据库部署模式',
                    trigger: 'change',
                  },
                ]"
              >
                <el-select
                  v-model="itemForm.dbDeployType"
                  placeholder="请选择数据库部署模式"
                >
                  <el-option
                    v-for="(b, index2) in schemaArr"
                    :key="index2"
                    :label="b.name"
                    :value="b.id"
                  ></el-option>
                </el-select>
              </el-form-item> -->
              <!-- 表达式配置 -->
              <el-form-item
                v-if="formUp.resultCheck"
                :label-width="formLabelWidthB"
              >
                <div slot="label">
                  <span
                    ><i style="color: #f56c6c; margin-right: 4px">*</i
                    >表达式配置</span
                  >
                  <el-tooltip class="item" effect="dark" placement="top-start">
                    <div slot="content">
                      <p>1. 符合下述表达式时则判定巡检结果正常;</p>
                      <p>2. 多个表达式时默认按”逻辑与“的关系处理;</p>
                    </div>
                    <i class="el-icon-question"></i>
                  </el-tooltip>
                </div>
                <div class="addExpression">
                  <el-button
                    type="primary"
                    icon="el-icon-circle-plus"
                    @click="itemFormAddRules(itemForm)"
                    >添加表达式</el-button
                  >
                </div>
                <div
                  class="flexBox"
                  v-for="(m, indexM) in itemForm.resultCheckRule.rules"
                  :key="indexM"
                >
                  <div class="expressionItem">
                    <el-form-item
                      :prop="`resultCheckRule.rules.` + indexM + '.ruleParam'"
                      :rules="[
                        {
                          validator: (rule, value, callback) =>
                            checkRuleParam(
                              rule,
                              value,
                              callback,
                              itemForm.resultCheckRule.rules
                            ),
                          trigger: 'change',
                        },
                      ]"
                    >
                      <el-select
                        v-model="m.ruleParam"
                        placeholder="巡检项参数"
                        clearable
                      >
                        <el-option
                          v-for="(c, index3) in itemForm.ruleParamArr"
                          :key="index3"
                          :label="`${c.value}(${c.label})`"
                          :value-key="c.label"
                          :value="c"
                        ></el-option>
                      </el-select>
                    </el-form-item>
                  </div>
                  <div class="expressionItem">
                    <el-form-item
                      :prop="
                        `resultCheckRule.rules.` + indexM + '.ruleOperator'
                      "
                      :rules="[
                        {
                          required: true,
                          message: '请选择数据库部署模式',
                          trigger: 'change',
                        },
                      ]"
                    >
                      <el-select
                        v-model="m.ruleOperator"
                        placeholder="表达式符号"
                        clearable
                      >
                        <el-option
                          v-for="(d, index4) in itemForm.ruleOperator"
                          :key="index4"
                          :label="d.label"
                          :value-key="d.label"
                          :value="d"
                        ></el-option>
                      </el-select>
                    </el-form-item>
                  </div>
                  <div class="expressionItem">
                    <el-form-item
                      :prop="`resultCheckRule.rules.` + indexM + '.ruleValue'"
                      :rules="[
                        {
                          required: true,
                          message: '请选择表达式符号',
                          trigger: 'change',
                        },
                      ]"
                    >
                      <el-input
                        v-model="m.ruleValue"
                        placeholder="请输入参数值"
                      ></el-input>
                    </el-form-item>
                  </div>
                  <div class="delBtn">
                    <i
                      v-if="indexM > 0"
                      class="el-icon-delete-solid"
                      @click="itemFormDeleteRules(itemForm, indexM)"
                    ></i>
                  </div>
                </div>
              </el-form-item>
            </el-form>
          </div>
        </div>
      </el-form-item>
    </el-form>
    <div class="drawer__footer">
      <el-button @click="cancelForm">取 消</el-button>
      <el-button
        type="primary"
        @click="submitForm(setDialogType)"
        :loading="loading"
        >{{ loading ? "提交中 ..." : "确 定" }}</el-button
      >
    </div>
  </div>
</template>
<script>
import * as requestMethod from "@/api/inspection/inspectionType/index.js";
export default {
  props: {
    folderData: {
      type: Array,
      default: () => [],
    },
    setDialogType: {
      type: String,
      default: () => "",
    },
    setDialogData: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    let checkExpression = (rule, value, callback, indexA) => {
      console.log("修改的能力模板内容", value);
      if (value == "") {
        callback("修改的能力模板内容");
      } else {
        callback();
      }
    };
    let checkRuleParam = (rule, value, callback, rulesArr) => {
      console.log("修改的能力模板内容", value);
      console.log("rulesArr", rulesArr);
      // 校验是否有重复的
      let hasRuleParamlength = rulesArr.filter(
        (a) => a.ruleParam.label == value.label
      ).length;
      if (value == "") {
        callback("请选择脚本参数");
      } else if (hasRuleParamlength > 1) {
        callback("脚本参数不能重复");
      } else {
        callback();
      }
    };
    return {
      checkExpression,
      checkRuleParam, // 校验表达式参数
      loading: false,
      // 上班部门表单
      formUp: {
        name: "", // 名称
        description: "", // 描述
        itemCategoryId: "", // 巡检项分类
        resourceCateId: "", // 资源分类
        itemLevels: [], // 用户
        resultCheck: true, // 结果判定,默认flase
        templateConfigList: [
          {
            abilityTemplateId: "", // 选择能力模板
            // 数据库部署模式,参数去掉了
            // dbDeployType: "",
            resultCheckRule: {
              // 表达式配置
              rules: [
                {
                  ruleParam: {
                    label: "", //
                    value: "", //
                  }, // 巡检项参数
                  ruleOperator: {
                    label: "",
                    value: "",
                  }, // 表达式符合
                  ruleValue: "", // 参数值
                },
              ], // 表达式配置
            },
            ruleParamArr: [], // 巡检项参数,由选择的能力模板决定
            ruleOperator: [], // 巡检参数表达式数据源
          },
        ],
      },
      formLabelWidth: "170px",
      formLabelWidthB: "128px", // 循环表单项宽度
      timer: null,
      // 数据源部分
      resourceArr: [], // 资源分类数据源
      powerArr: [], // 能力模板数据源
      schemaArr: [], // 数据库部署模式数据源
      // parameterArr: [], // 巡检项参数,数据源
      // 巡检项分类展示取参
      showProps: {
        value: "id",
        label: "name",
      },
    };
  },
  created() {
    // 此处接口获取数据源,下面模拟数据
    this.getResourceArr();
  },
  mounted() {
    console.log("row", this.setDialogData);
    if (this.setDialogType == "edit") {
      let {
        name,
        description,
        itemCategoryId,
        resourceCateId,
        itemLevels,
        resultCheck,
        templateConfigList,
      } = this.setDialogData;
      this.formUp.name = name; // 名称
      this.formUp.description = description; // 描述
      this.formUp.itemCategoryId = [itemCategoryId]; // 巡检项分类
      this.formUp.resourceCateId = resourceCateId; // 资源分类
      this.formUp.itemLevels = itemLevels; // 用户
      this.formUp.resultCheck = resultCheck; // 结果判定,默认flase
      this.formUp.templateConfigList = templateConfigList.map((a) => {
        let objTemplateConfig = {
          abilityTemplateId: a.abilityTemplateId,
          abilityTemplateName: a.abilityTemplateName,
          resultCheckRule: a.resultCheckRule,
          ruleParamArr: [], // 巡检项参数,由选择的能力模板决定
          ruleOperator: [], // 巡检参数表达式数据源
        };
        return objTemplateConfig;
      });
      // 根据资源分类,查询模板参数数据源,处理配置templateConfigList每项的ruleParamArr/ruleOperator
      this.editFormUpTemplateList(resourceCateId); //
    }
    // 部署模式固定数据
    // this.schemaArr = [
    //   { id: "RAC", name: "RAC" },
    //   { id: "Single", name: "单节点" },
    //   { id: "PowerHA", name: "powerHA" },
    // ];
  },
  methods: {
    // 获取资源分类
    getResourceArr() {
      requestMethod.getResoureConfig("get").then((res) => {
        if (res.status || res.code == 200) {
          this.resourceArr = res.data;
        }
      });
    },
    // 资源分类修改,获取对应的能力模板数据
    getTemplateArr(e) {
      console.log("选择的资源分类", e);
      let parmas = {
        resourceCateId: e,
      };
      requestMethod.getTemplateConfig("get", parmas).then((res) => {
        if (res.status || res.code == 200) {
          this.powerArr = res.data;
        }
      });
    },
    editFormUpTemplateList(id) {
      let parmas = {
        resourceCateId: id,
      };
      requestMethod.getTemplateConfig("get", parmas).then((res) => {
        let that = this;
        if (res.status || res.code == 200) {
          this.powerArr = res.data;
          let zzPowerArr = res.data;
          // 处理现有的数据
          this.formUp.templateConfigList = this.formUp.templateConfigList.map(
            (m) => {
              zzPowerArr.map((n) => {
                if (n.id == m.abilityTemplateId) {
                  m.ruleParamArr = that.objToArray(n.downParaStruct); // 巡检项参数,由选择的能力模板决定
                  m.ruleOperator = n.ruleOperators; // 巡检参数表达式数据源
                }
                return true;
              });
              return m;
            }
          );
        }
      });
    },
    // 当前能力模板的,模板修改,查询对应的表达式参数以及数据源
    changeItemTemplate(abilityTemplateId, itemForm) {
      console.log("templateId", abilityTemplateId);
      console.log("itemForm", itemForm);
      requestMethod.getTemplateKeys("get", abilityTemplateId).then((res) => {
        if (res.status || res.code == 200) {
          itemForm.ruleParamArr = this.objToArray(res.data.downParaStruct); // 当前模板的巡检参数数据源
          itemForm.ruleOperator = res.data.ruleOperators; // 当前模板表达式数据源
        }
      });
    },
    // 把对象属性参数,转成数组对象
    objToArray(obj) {
      return Object.entries(obj).map(([name, value]) => ({
        label: value.note,
        value: name,
        type: value.valueType,
        // required: value.required,
      }));
    },
    //  能力模板新增表达式
    itemFormAddRules(itemForm) {
      let obj = {
        ruleParam: {
          label: "", //
          value: "", //
        }, // 巡检项参数
        ruleOperator: {
          label: "",
          value: "",
        }, // 表达式符合
        ruleValue: "", // 参数值
      };
      itemForm.resultCheckRule.rules = [...itemForm.resultCheckRule.rules, obj];
    },
    // 能力模板表单删除表达式
    itemFormDeleteRules(itemForm, indexM) {
      itemForm.resultCheckRule.rules.splice(indexM, 1);
    },
    // 新增大块的能力模板
    addTemplate(templateConfigList) {
      let templateObject = {
        abilityTemplateId: "", // 选择能力模板
        // dbDeployType: "", // 数据库部署模式
        resultCheckRule: {
          // 表达式配置
          rules: [
            {
              ruleParam: {
                label: "", //
                value: "", //
              }, // 巡检项参数
              ruleOperator: {
                label: "",
                value: "",
              }, // 表达式符合
              ruleValue: "", // 参数值
            },
          ], // 表达式配置
        },
        ruleParamArr: [], // 巡检项参数,由选择的能力模板决定
        ruleOperator: [], // 巡检参数表达式数据源
      };
      this.formUp.templateConfigList = [...templateConfigList, templateObject];
    },
    // 删除大块的能力模板
    deleteTemplate(indexA) {
      this.formUp.templateConfigList.splice(indexA, 1);
    },
    // 取消
    cancelForm() {
      this.loading = false;
      this.$emit("closeSetDialog");
    },
    // 确定
    submitForm(type) {
      this.$refs["formUp"].validate((valid) => {
        if (valid) {
          // 把itemCategoryId重数组转成字符串
          this.formUp.itemCategoryId = this.formUp.itemCategoryId.join();
          let vo = this.formUp;
          let xjxId = type == "edit" ? this.setDialogData.id : ""; // 巡检项Id
          if (type == "add") {
            requestMethod.setInspection("post", vo).then((res) => {
              if (res.status) {
                this.$message.success("定义巡检项成功");
                // 按照左侧数据筛选,重新获取列表数据
                this.$emit("closeSetDialog", "getList");
              }
            });
          } else if (type == "edit") {
            requestMethod.editInspection("put", vo, xjxId).then((res) => {
              if (res.status) {
                this.$message.success("配置巡检项成功");
                // 按照左侧数据筛选,重新获取列表数据
                this.$emit("closeSetDialog", "getList");
              }
            });
          }
        } else {
          return false;
        }
      });
    },
  },
};
</script>
<style lang='less' scoped>
.drawer__content {
  padding: 15px;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: auto;
  form {
    flex: 1;
  }
  .borderRight {
    border-right: 1px solid #d9dde0;
    padding-right: 30px;
  }
}
.drawer__footer {
  text-align: right;
  border-top: 1px solid #e7edf3;
  padding-top: 10px;
}
// 能力模板样式处理
.formContent {
  margin-top: 10px;
  .formItem {
    border: 1px solid #e7edf3;
    padding: 0 10px;
    h4 {
      border-bottom: 1px solid #e7edf3;
      margin-bottom: 15px;
    }
    .addExpression {
      margin-bottom: 15px;
    }
    .flexBox {
      display: flex;
      align-items: flex-start;
      .expressionItem {
        flex: 1;
        margin-right: 10px;
      }
      .delBtn {
        width: 30px;
        font-size: 16px;
        cursor: pointer;
      }
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值