Bootstrap

el-from表单动态新增,el-select主级选择完之后次级就不能再次选择同样的选项

需求描述:
主闸站的闸站选择和次闸站的闸站选择下拉框是同一个接口,但是要求是主闸站选择完一个选项之后,次闸站不可以再选择了,然后次次闸站也不可以选择上面两个已经选择过的

效果图
在这里插入图片描述

接口数据结构
在这里插入图片描述
因为我这个表单是动态新增的,所以直接代码部分全部展示出来算了

在这里用到了Object.freeze(),具体用法及介绍
https://juejin.cn/post/6844903922469961741

<template>
  <el-dialog
    v-bind="dialogConfig"
    :visible.sync="visibleTmpl"
    :before-close="beforeClose"
    :title="rulesProps.title"
    append-to-body
    width="700px"
    class="index_station_addDialog"
  >
    <el-form
      :model="form"
      :label-position="'left'"
      label-width="120px"
      size="small"
      ref="addForm"
    >
      <el-form-item
        prop="name"
        label="方案名称:"
        class="pa_l"
        :rules="[
          {
            required: true,
            message: '方案名称不能为空',
            trigger: 'blur',
          },
        ]"
      >
        <el-input
          v-model="form.name"
          placeholder="请输入方案名称"
          :disabled="!rulesProps.detailView"
          maxlength="30"
          type="text"
          show-word-limit
        />
      </el-form-item>
      <el-form-item
        prop="description"
        label="关联说明:"
        class="pa_l"
        :rules="[
          {
            required: true,
            message: '关联说明不能为空',
            trigger: 'blur',
          },
        ]"
      >
        <el-input
          type="textarea"
          placeholder="请输入关联说明"
          v-model="form.description"
          maxlength="999"
          show-word-limit
          :disabled="!rulesProps.detailView"
        />
      </el-form-item>
      <!-- 主闸站 -->
      <el-row class="main_station">
        <el-col :span="24">
          <div class="title">主闸站</div>
          <el-form-item
            prop="stationId"
            label="闸站选择: "
            :rules="[
              {
                required: true,
                message: '闸站不能为空',
                trigger: 'change',
              },
            ]"
          >
            <el-select
              v-model="form.stationId"
              filterable
              :disabled="!rulesProps.detailView"
              placeholder="请选择闸站"
              @change="hanheStationChange"
            >
              <el-option
                v-for="item in options.mainOptions"
                :key="item.nodeId"
                :label="item.nodeName"
                :value="item.nodeId"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            prop="onOrOff"
            label="闸站启闭控制: "
            :rules="[
              {
                required: true,
                message: '请选择闸站启闭控制',
                trigger: 'change',
              },
            ]"
          >
            <el-radio
              v-model="form.onOrOff"
              :label="1"
              :disabled="!rulesProps.detailView"
              ></el-radio
            >
            <el-radio
              v-model="form.onOrOff"
              :label="0"
              :disabled="!rulesProps.detailView"
              ></el-radio
            >
          </el-form-item>
        </el-col>
      </el-row>
      <!-- 次闸站 -->
      <el-row
        v-for="(item, index) in form.gssList"
        :key="index"
        class="main_station"
      >
        <el-col :span="24">
          <div class="title">
            次闸站
            <span
              class="del"
              v-if="form.gssList.length > 1"
              @click="deleteSubjectBtn(item, index)"
              >x</span
            >
          </div>
          <el-form-item
            label="闸站选择 :"
            :prop="'gssList.' + index + '.stationId'"
            :rules="[
              {
                required: true,
                message: '闸站不能为空',
                trigger: 'change',
              },
            ]"
          >
            <el-select
              v-model="item.stationId"
              filterable
              :disabled="!rulesProps.detailView"
              placeholder="请选择闸站"
              @change="changeHandle"
            >
              <el-option
                v-for="val in options.secondaryOptions"
                :key="val.nodeId"
                :label="val.nodeName"
                :value="val.nodeId"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            label="闸站启闭控制 :"
            :prop="'gssList.' + index + '.onOrOff'"
            :rules="[
              {
                required: true,
                message: '请选择闸站启闭控制',
                trigger: 'change',
              },
            ]"
          >
            <el-radio
              v-model="item.onOrOff"
              :label="1"
              :disabled="!rulesProps.detailView"
              ></el-radio
            >
            <el-radio
              v-model="item.onOrOff"
              :label="0"
              :disabled="!rulesProps.detailView"
              ></el-radio
            >
          </el-form-item>
          <el-form-item
            label="是否反向关联控制 :"
            :prop="'gssList.' + index + '.isReverseControl'"
            class="float_r"
          >
            <el-switch
              v-model="item.isReverseControl"
              :active-value="0"
              :inactive-value="1"
              active-color="#dcdfe6"
              inactive-color="#34b28a"
              :disabled="!rulesProps.detailView"
            >
            </el-switch>
          </el-form-item>
        </el-col>
      </el-row>

      <div v-if="rulesProps.detailView && !isView">
        <el-button type="primary" size="small" @click="addList"
          >新增次级关联</el-button
        >
      </div>
    </el-form>
    <span slot="footer" class="dialog-footer" v-if="rulesProps.detailView">
      <el-button @click="handleBack"> </el-button>
      <el-button type="primary" @click="onSubmit"> </el-button>
    </span>
  </el-dialog>
</template>

<script>
import { addStationList, queryWaterGateList } from "@/api/basic/getStation";

export default {
  data() {
    return {
      // 弹窗显示/隐藏
      visibleTmpl: this.visible,
      form: this.initFormData(),
      isView: false,
      defaultOption: Object.freeze([]),
      options: {
        mainOptions: [], // 主级闸坝
        secondaryOptions: [], // 次级闸坝
      },

      dialogTitle: "",
      list: [],
    };
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    dialogProps: {
      type: Object,
      default: () => {},
    },
    rulesProps: {
      type: Object,
      default: () => {},
    },
  },
  created() {
    this.queryWaterGateList();
    if (this.rulesProps.id) {
      this.form = this.dialogProps;
      // Object.assign({}, this.form, this.dialogProps);
    }
  },
  methods: {
    // 初始化表单
    initFormData() {
      return {
        name: "", // 方案名称
        description: "", // 关联说明
        stationId: "", // 闸站选择
        onOrOff: 1, // 闸站启闭控制

        gssList: [
          {
            isReverseControl: 1, //是否反向控制
            stationId: "", // 闸站选择
            onOrOff: 1, // 闸站启闭控制
          },
        ], // 次闸站
      };
    },
    // 获取闸站下拉数组
    queryWaterGateList() {
      setTimeout(async () => {
        try {
          const res = await queryWaterGateList();
          this.options.mainOptions = res.data || [];
          this.options.secondaryOptions = res.data || [];
        } catch (error) {
          console.log(error);
        }
      }, 1000);
    },

    // 新增次级关联
    addList() {
      this.form.gssList.push({
        isReverseControl: 1, //是否反向控制
        stationId: "", // 闸站选择
        onOrOff: "", // 闸站启闭控制
      });
    },
    // 删除次级关联
    deleteSubjectBtn(item, subIndex) {
      this.form.gssList.splice(subIndex, 1);
    },
    // 关闭弹窗
    beforeClose(done) {
      this.$emit("update:visible", false);
      this.$emit("submit");
      done();
      this.$refs["addForm"].resetFields();
      this.form.name = "";
      this.form.description = "";
      this.form.stationId = "";
      this.form.onOrOff = 1;
      this.form.gssList = [];
    },
    handleBack() {
      this.$emit("update:visible", false);
    },
    // 提交表单
    onSubmit() {
      this.$refs["addForm"].validate(async (valid) => {
        if (valid) {
          try {
            const res = await addStationList(this.form);
            console.log(res, 22222);

            this.$message({
              message: "新增调度方案成功",
              type: "success",
            });
            this.$emit("submit");
            this.$emit("update:visible", false);
          } catch (error) {
            console.log(error);
            this.$emit("submit");
            this.$emit("update:visible", false);
          }
        }
      });
    },
    // 主级闸坝选择
    hanheStationChange(data) {
      this.options.secondaryOptions = this.options.mainOptions.filter((val) => {
        return ![data].includes(val.nodeId);
      });
      this.defaultOption = Object.freeze(this.options.secondaryOptions);
    },
    // 次闸站下拉数据数组
    changeHandle(value) {
      this.options.secondaryOptions = this.defaultOption.filter(
        (item) => !this.form.gssList.some((_) => _.stationId === item.nodeId)
      );
      if (this.options.secondaryOptions.length < 1) {
        this.isView = true;
      }
    },
  },

  computed: {
    dialogConfig() {
      return Object.assign({}, this.dialogProps);
    },
  },
  watch: {
    visible(n) {
      this.visibleTmpl = n;
    },
  },
};
</script>

<style lang="scss" >
.index_station_addDialog {
  .title {
    font-size: 16px;
    font-weight: 500;
    margin-bottom: 8px;
    color: #606266;
    .del {
      float: right;
      cursor: pointer;
    }
  }
  .main_station {
    border: 1px solid #dcdfe6;
    padding: 8px 16px 0 16px;
    margin-bottom: 16px;
    .el-form-item {
      margin-left: 16px;
    }
  }
  .pa_l {
    .el-form-item__label {
      padding-left: 20px;
    }
  }
  .float_r {
    float: right;
    width: 180px !important;

    .el-form-item__label {
      width: 140px !important;
    }
  }
  .el-select {
    width: 100%;
  }
  .el-textarea__inner {
    font-family: "微软雅黑";
  }
}
</style>

;