vue中实现级联选择功能

实现效果图

在这里插入图片描述

实现功能描述

当前下拉框选中数据为下一个下拉框数据来源的依据,即当前节点为下一选择框数据的父节点,并且当前选择框选中数据更改时,后面的选择框数据也需同步更新。

实现思路

  1. 默认请求第一层数据接口(这里指的是“分公司”这一级数据)
  2. watch监听当前选中的“分公司”值变化时,请求下一级数据源(这里指供热处这一级数据)【在请求数据前先重置下面所有表单项,避免在都选择完后更改某一下拉框,造成有些数据源和选中项还是一次的数据问题】,后面的逻辑就一样。

主要代码

<template>
	<el-dialog
      title="新增"
      :visible.sync="addVisible"
      v-if="addVisible"
      :before-close="addVisibleClose"
      :width="'600px'"
      :close-on-click-modal="false"
    >
      <el-form
        ref="addForm"
        :model="addForm"
        label-width="90px"
        :rules="addRules"
      >
        <el-row :gutter="24">
          <el-col :span="24" style="padding-right: 0">
            <el-form-item label="分公司:" prop="comId">
              <el-select
                placeholder="请选择分公司"
                v-model="addForm.comId"
                style="width: 90%"
                @change="changeCom"
              >
                <el-option
                  v-for="item in coms"
                  :label="item.label"
                  :key="item.id"
                  :value="item.id"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" style="padding-right: 0">
            <el-form-item label="供热处:" prop="heatingId">
              <el-select
                placeholder="请选择供热处"
                v-model="addForm.heatingId"
                style="width: 90%"
                @change="changeGrcs"
              >
                <el-option
                  v-for="item in grcs"
                  :label="item.label"
                  :key="item.id"
                  :value="item.id"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" style="padding-right: 0">
            <el-form-item label="中心站:" prop="centralStationId">
              <el-select
                placeholder="请选择中心站"
                v-model="addForm.centralStationId"
                style="width: 90%"
                @change="changeZxzs"
              >
                <el-option
                  v-for="item in zxzs"
                  :label="item.label"
                  :key="item.id"
                  :value="item.id"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" :xs="24" style="padding-right: 0">
            <el-form-item label="小区:" prop="areaId">
              <el-select
                placeholder="请选择小区"
                v-model="addForm.areaId"
                style="width: 90%"
                @change="changeAreas"
              >
                <el-option
                  v-for="item in areas"
                  :label="item.label"
                  :key="item.id"
                  :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" :xs="24" style="padding-right: 0">
            <el-form-item label="楼栋:" prop="buildId">
              <el-select
                placeholder="请选择楼栋"
                v-model="addForm.buildId"
                style="width: 90%"
                @change="changeBuilds"
              >
                <el-option
                  v-for="item in builds"
                  :label="item.label"
                  :key="item.id"
                  :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" :xs="24" style="padding-right: 0">
            <el-form-item label="单元:" prop="unitId">
              <el-select
                placeholder="请选择单元"
                v-model="addForm.unitId"
                style="width: 90%"
                @change="changeUnits"
              >
                <el-option
                  v-for="item in units"
                  :label="item.label"
                  :key="item.id"
                  :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24" :xs="24" style="padding-right: 0">
            <el-form-item label="高/底区:" prop="roomName">
              <el-input
                v-model="addForm.roomName"
                placeholder="请输入高/底区"
                style="width: 90%"
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addVisibleClose">取 消</el-button>
        <el-button type="primary" @click="addVisibleOk">确 定</el-button>
      </span>
    </el-dialog>
</template>

<script>
export default {
	data() {
		return {
			coms: [],
      		grcs: [],
      		zxzs: [],
      		areas: [],
      		builds: [],
      		units: [],
      		addForm: {
        		comId: "",
        		comName: "",
        		heatingId: "",
        		heatingName: "",
        		centralStationId: "",
        		centralStationName: "",
        		areaId: "",
        		areaName: "",
        		buildId: "",
        		buildName: "",
        		unitId: "",
        		unitName: "",
        		roomName: "",
      		},
      		addRules: {
        		comId: [{ required: true, message: "请选择分公司", trigger: "change" }],
        		heatingId: [{ required: true, message: "请选择供热处", trigger: "change"}],
        		centralStationId: [{ required: true, message: "请选择中心站", trigger: "change" }],
        		areaId: [{ required: true, message: "请选择小区", trigger: "change" }],
        		buildId: [{ required: true, message: "请选择楼栋", trigger: "change" }],
        		unitId: [{ required: true, message: "请选择单元", trigger: "change" }],
      		}
		}
	},
	watch: {
    "addForm.comId": {
      immediate: true,
      handler(value) {
        if (!!value) {
          this.addForm.heatingId = "";
          this.addForm.heatingName = "";
          this.addForm.centralStationId = "";
          this.addForm.centralStationName = "";
          this.addForm.areaId = "";
          this.addForm.areaName = "";
          this.addForm.buildId = "";
          this.addForm.buildName = "";
          this.addForm.unitId = "";
          this.addForm.unitName = "";
          // this.addForm.roomName = "";
          this.grcs = [];
          this.zxzs = [];
          this.areas = [];
          this.builds = [];
          this.units = [];
          this.getGrcs();
        }
      },
    },
    "addForm.heatingId": {
      immediate: true,
      handler(value) {
        if (!!value) {
          this.addForm.centralStationId = "";
          this.addForm.centralStationName = "";
          this.addForm.areaId = "";
          this.addForm.areaName = "";
          this.addForm.buildId = "";
          this.addForm.buildName = "";
          this.addForm.unitId = "";
          this.addForm.unitName = "";
          // this.addForm.roomName = "";
          this.zxzs = [];
          this.areas = [];
          this.builds = [];
          this.units = [];
          this.getZxzs();
        }
      },
    },
    "addForm.centralStationId": {
      immediate: true,
      handler(value) {
        if (!!value) {
          this.addForm.areaId = "";
          this.addForm.areaName = "";
          this.addForm.buildId = "";
          this.addForm.buildName = "";
          this.addForm.unitId = "";
          this.addForm.unitName = "";
          // this.addForm.roomName = "";
          this.areas = [];
          this.builds = [];
          this.units = [];
          this.getArea();
        }
      },
    },
    "addForm.areaId": {
      immediate: true,
      handler(value) {
        if (!!value) {
          this.addForm.buildId = "";
          this.addForm.buildName = "";
          this.addForm.unitId = "";
          this.addForm.unitName = "";
          // this.addForm.roomName = "";
          this.builds = [];
          this.units = [];
          this.getBuild();
        }
      },
    },
    "addForm.buildId": {
      immediate: true,
      handler(value) {
        if (!!value) {
          this.addForm.unitId = "";
          this.addForm.unitName = "";
          // this.addForm.roomName = "";
          this.units = [];
          this.getUnit();
        }
      },
    },
  },
  methods: {
  	// 我这里监听change是因为接口也需要传选中项的名字(看需要添加)
  	changeCom(value) {
      const selectedOption = this.coms.find((option) => option.id === value);
      this.addForm.comName = selectedOption?.label;
    },
    changeGrcs(value) {
      const selectedOption = this.grcs.find((option) => option.id === value);
      this.addForm.heatingName = selectedOption?.label;
    },
    changeZxzs(value) {
      const selectedOption = this.zxzs.find((option) => option.id === value);
      this.addForm.centralStationName = selectedOption?.label;
    },
    changeAreas(value) {
      const selectedOption = this.areas.find((option) => option.id === value);
      this.addForm.areaName = selectedOption?.label;
    },
    changeBuilds(value) {
      const selectedOption = this.builds.find((option) => option.id === value);
      this.addForm.buildName = selectedOption?.label;
    },
    changeUnits(value) {
      const selectedOption = this.units.find((option) => option.id === value);
      this.addForm.unitName = selectedOption?.label;
    },
    // 第一级数据源,即分公司(在dialog显示就获取)
    getOrgs() {
      const data = {
        equipType: "t_org_customer",
        level: this.$store.state.user.user.dept.deptLevel,
        id: this.$store.state.user.user.dept.deptId,
      };
      listLazyDept(data).then(({ data }) => {
        this.coms = data;
      });
    },
    getGrcs() {
      const params = {
        equipType: "t_org_customer",
        level: "fgs",
        id: this.addForm.comId,
      };
      listLazyDept(params).then(({ data }) => {
        this.grcs = data;
      });
    },
    getZxzs() {
      const params = {
        equipType: "t_org_customer",
        level: "grc",
        id: this.addForm.heatingId,
      };
      listLazyDept(params).then(({ data }) => {
        this.zxzs = data;
      });
    },
    getArea() {
      const params = {
        equipType: "t_org_customer",
        level: "zxz",
        id: this.addForm.centralStationId,
      };
      listLazyDept(params).then(({ data }) => {
        this.areas = data;
      });
    },
    getBuild() {
      const params = {
        equipType: "t_org_customer",
        level: "xq",
        id: this.addForm.areaId,
      };
      listLazyDept(params).then(({ data }) => {
        this.builds = data;
      });
    },
    getUnit() {
      const params = {
        equipType: "t_org_customer",
        level: "ld",
        id: this.addForm.buildId,
      };
      listLazyDept(params).then(({ data }) => {
        this.units = data;
      });
    },
    // 点击【新增】出发的方法
    addFun() {
      this.coms = [];
      this.grcs = [];
      this.zxzs = [];
      this.areas = [];
      this.builds = [];
      this.units = [];
      this.addForm = {
        comId: "",
        comName: "",
        heatingId: "",
        heatingName: "",
        centralStationId: "",
        areaId: "",
        areaName: "",
        buildId: "",
        buildName: "",
        unitId: "",
        unitName: "",
      };
      this.getOrgs();
      this.addVisible = true;
    },
    addVisibleClose() {
      this.addVisible = false;
    },
    addVisibleOk() {
      this.$refs.addForm.validate((valid) => {
        if (valid) {
          this.$modal.loading("请稍候...");
          let data = {
            ...this.addForm,
            equipType: "cjq_add",
          };
          jcqSaveApi(data)
            .then(() => {
              this.$message({
                type: "success",
                message: "新增成功!",
              });
              this.getList();
            })
            .finally(() => {
              this.addVisible = false;
              this.$modal.closeLoading();
            });
        }
      });
    },
  },
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值