vue2 复杂的el-form 嵌套多个el-table 实现el-table 里面的校验

344 阅读2分钟
<template>
  <div class="root-box">
    <el-form
      class="elForm"
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="180px"
    >
      <!--  -->
      <div class="header">
        <span class="title">基础信息配置</span>
      </div>
      <el-row>
        <el-col :span="8">
          <el-form-item label="权益包名称:" prop="name" :rules="rules.name">
            <el-input
              v-model="ruleForm.name"
              placeholder="请输入"
              maxlength="100"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item
            label="权益有效期:"
            prop="rightTime"
            :rules="rules.rightTime"
          >
            <el-input
              style="width: 80px"
              v-model="ruleForm.rightTime"
              placeholder="请输入"
              maxlength="3"
            />

            <el-select
              style="width: 120px; margin-left: 8px"
              v-model="ruleForm.timeFormat"
              placeholder="请选择"
            >
              <el-option
                v-for="item in timeOption"
                :key="item.key"
                :label="item.label"
                :value="item.key"
              />
            </el-select>
          </el-form-item>

        
        </el-col>
        <el-col :span="8">
          <el-form-item label="权益包金额:" prop="mount" :rules="rules.mount">
            <el-input
              style="width: 100px"
              v-model="ruleForm.mount"
              placeholder="请输入"
              maxlength="6"
            />
            <span style="margin-left:8px;"></span>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-form-item label="权益包渠道商:" prop="channelCompany" :rules="rules.channelCompany">
          <el-cascader
            style="width:306px;"
            v-model="ruleForm.channelCompany"
            :options="channelCompanyList"
            :props="{
              children: 'subDTO',
              label: 'companyShortName',
              value: 'companyId',
            }"
            clearable
            filterable
            show-all-levels
          />
        </el-form-item>
      </el-row>

      <el-row>
        <el-form-item label="备注说明:" prop="remark">
          <el-input
            style="width: 690px"
            type="textarea"
            v-model="ruleForm.remark"
            maxlength="300"
            placeholder="请输入"
            :rows="3"
          />
        </el-form-item>
      </el-row>

      <div class="header">
        <span class="title">权益配置</span>
      </div>

      <div class="right-box">
        <div v-for="(quanyi, index) in ruleForm.quanyi" :key="index">
          <div>权益{{ index + 1 }}</div>

          <el-row>
            <el-col :span="12">
              <el-form-item
                label="权益名称:"
                :prop="'quanyi.' + index + '.quanyiName'"
                :rules="rules.quanyiName"
              >
                <el-select placeholder="请选择" v-model="quanyi.quanyiName">
                  <el-option
                    v-for="item in rightOption"
                    :key="item.key"
                    :label="item.label"
                    :value="item.label"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                label="权益有效期起期:"
                :prop="'quanyi.' + index + '.rangeTime'"
                :rules="rules.rangeTime"
              >
                <el-select placeholder="请选择" v-model="quanyi.rangeTime">
                  <el-option
                    v-for="item in rightOption"
                    :key="item.key"
                    :label="item.label"
                    :value="item.key"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>

          <!-- 动态生成 el-table -->
          <el-table :data="quanyi.tableList" border style="margin-bottom: 50px">
            <el-table-column
              prop="yuefen"
              label="月份"
              align="center"
            ></el-table-column>
            <el-table-column prop="number" label="数量" align="center">
              <template slot-scope="scope">
                <template v-if="scope.row.editable">
                  <el-form-item
                    label-width="20px"
                    :prop="
                      'quanyi.' +
                      index +
                      '.tableList.' +
                      scope.$index +
                      '.number'
                    "
                    :rules="rules.number"
                  >
                    <el-input
                      v-model="scope.row.number"
                      maxlength="10"
                    />
                  </el-form-item>
                </template>

                <template v-else>
                  {{ scope.row.number }}
                </template>
              </template>
            </el-table-column>
            <el-table-column prop="time" label="有效期" align="center">
              <template slot-scope="scope">
                 <template v-if="scope.row.editable">
                   <el-form-item
                  label-width="20px"
                  :prop="
                    'quanyi.' + index + '.tableList.' + scope.$index + '.time'
                  "
                  :rules="rules.time"
                >
                    <el-input
                      v-model="scope.row.time"
                      maxlength="10"
                    />
                  </el-form-item>
                </template>
                <template v-else>
                    {{ scope.row.time }}
                </template>
              </template>
            </el-table-column>

            <el-table-column prop="unit" label="有效期单位" align="center">
              <template slot-scope="scope">
                 <template v-if="scope.row.editable">
                <el-form-item
                  label-width="20px"
                  :prop="
                    'quanyi.' + index + '.tableList.' + scope.$index + '.unit'
                  "
                  :rules="rules.unit"
                >
                  <el-select v-model="scope.row.unit" placeholder="请选择">
                    <el-option
                      v-for="item in timeOption"
                      :key="item.key"
                      :label="item.label"
                      :value="item.key"
                    />
                  </el-select>
                </el-form-item>
                 </template>
                 <template v-else>
                    {{ scope.row.unit }}
                </template>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </el-form>

    <actions-bottom>
      <el-button type="primary" @click="addNewRight">新增权益</el-button>
      <el-button style="margin-left: 50px">取消</el-button>
      <el-button type="primary" style="margin-left: 20px" @click="save"
        >确定</el-button
      >
    </actions-bottom>
  </div>
</template>

<script>
import ActionsBottom from "./components/actionsBottom.vue";
export default {
  name: "AddRight",
  components: {
    ActionsBottom,
  },

  data() {
    return {
      ruleForm: {
        timeFormat:'月',
        quanyi: [
          {
            quanyi1: "",
            quanyiName: "权益名称1",
            rangeTime: "",
            tableList: [
              { yuefen: "1月", number: "2", time: "1", unit: "月" },
              { yuefen: "2月", number: "2", time: "1", unit: "月" },
              { yuefen: "3月", number: "2", time: "1", unit: "月" },
              { yuefen: "4月", number: "2", time: "1", unit: "月" },
              { yuefen: "5月", number: "2", time: "1", unit: "月" },
              { yuefen: "6月", number: "2", time: "1", unit: "月" },
              { yuefen: "7月", number: "2", time: "1", unit: "月" },
              { yuefen: "8月", number: "2", time: "1", unit: "月" },
              { yuefen: "9月", number: "2", time: "1", unit: "月" },
              { yuefen: "10月", number: "2", time: "1", unit: "月" },
              { yuefen: "11月", number: "2", time: "1", unit: "月" },
              { yuefen: "12月", number: "2", time: "1", unit: "月" },
            ],
          },
        ],
      },
      rules: {
        name: [{ required: true, message: "请输入", trigger: "blur" }],
        rightTime: [{ required: true, message: "请输入", trigger: "blur" },{ pattern: /^\d{1,3}$/, message: '1-3位数字', trigger: 'blur' }],
        mount: [{ required: true, message: "请输入", trigger: "blur" },{ pattern: /^\d{1,6}$/, message: '1-6位数字', trigger: 'blur' }],
        channelCompany: [{ required: true, message: "请输入", trigger: "change" }],
        quanyi1: [{ required: true, message: "请输入", trigger: "blur" }],
        quanyiName: [{ required: true, message: "请输入", trigger: "change" }],
        rangeTime: [{ required: true, message: "请输入", trigger: "change" }],
        number: [{ required: true, message: "请输入数量", trigger: "blur" },{ pattern: /^\d{1,6}$/, message: '1-6位数字', trigger: 'blur' }],
        time: [{ required: true, message: "请输入有效期", trigger: "blur" },{ pattern: /^\d{1,6}$/, message: '1-6位数字', trigger: 'blur' }],
      },
      timeOption: [
        { key: "年", label: "年" },
        { key: "月", label: "月" },
        { key: "日", label: "日" },
      ],
      rightOption: [
        { key: "权益名称1", label: "权益名称1" },
        { key: "权益名称2", label: "权益名称2" },
      ],
      selectCompany: "",
      channelCompanyList: [
        {
          companyId: 1,
          companyLevel: "0",
          companyMark: "10000000_10000000",
          companyName: "总公司",
          companyNo: null,
          companyShortName: "总公司",
          companySubNo: null,
          disabled: null,
          ruleNum: null,
          state: "1",
          subDTO: [
            {
              companyId: 1526,
              companyLevel: "1",
              companyMark: "TSLCN_00000",
              companyName: "拓速乐中国有限公司",
              companyNo: null,
              companyShortName: "拓速乐中国",
              companySubNo: null,
              disabled: null,
              ruleNum: null,
              state: "1",
              subDTO: [
                {
                  companyId: 1527,
                  companyLevel: "2",
                  companyMark: "TSLCN_01000",
                  companyName: "拓速乐中国有限公司广东分公司",
                  companyNo: null,
                  companyShortName: "拓速乐广东",
                  companySubNo: null,
                  disabled: null,
                  ruleNum: null,
                  state: "1",
                  treePath: "1/1526/1527",
                },
              ],
              treePath: "1/1526",
            },
          ],
          treePath: "1",
        },
      ],
    };
  },
  methods: {
    async save() {
      console.log("ruleForm", this.ruleForm);
      const isValid = await this.$refs.ruleForm.validate();
      console.log("isValid", isValid);
      if (!isValid) {
        return;
      }
    },
    addNewRight() {
      const right = {
        quanyi1: "权益2",
        quanyiName: "",
        rangeTime: "",
        tableList: [
          { yuefen: "1月", number: "", time: "", unit: "", editable: true },
          { yuefen: "2月", number: "", time: "", unit: "", editable: true },
          { yuefen: "3月", number: "", time: "", unit: "", editable: true },
        ],
      };
      this.ruleForm.quanyi.push(right);
    },
  },
};
</script>

<style lang="scss" scoped>
.root-box {
  .header {
    width: 100%;
    height: 48px;
    margin-bottom: 16px;
    background: #ffffff;
    box-shadow: inset 0px -1px 0px 0px rgba(230, 230, 230, 1);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 24px 10px 24px;

    .title {
      font-family: PingFangSC-Medium;
      font-size: 16px;
      color: #383838;
      letter-spacing: 0;
      font-weight: bold;
    }
  }
  .right-box {
    margin: 10px 150px 80px 150px;
    .centered-cell {
      display: flex;
      align-items: center; // 垂直居中
      justify-content: center; // 水平居中(如果需要)
    }
  }
  .footer {
    position: fixed;
    bottom: 0;
    width: 100%;
    height: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>