VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > JavaScript教程 >
  • 基于elementUI的Cascader组件封装的多功能地区区划选择器(可回显、接口懒加载)

注:公司领导要求封装一个区划选择器,最大支持五级区划,并且适用的场景有很多:数据全部由接口所得并且是懒加载形式;能够回显当前登录账号所属级别的默认地址;还能够回显接口返回的默认地址;能够配置区划选择器的最大级别;禁止当前级别之前的地址被选择等等功能,花了两天的事时间,终于算是完善优化好了,供大家一起参考,代码若有缺陷还望指针,感谢!以下是源代码:

特别说明:这里面使用懒加载形式调取接口,每次接口返回一个级别的数据,如第一次默认返回所有省级,点击安徽省,传安徽省code则再次调用接口返回安徽省下所有地级市的数据,依次类推;这里接口返回的数组中,必须要有的参数:[{name:'级别名称',id:'级别code值'}]

技术栈:VUE+ElementUI

组件areaCascader.vue

复制代码
<template>
  <div>
    <el-tooltip
      effect="dark"
      :content="addressName"
      placement="top"
      :enterable="false"
      :disabled="disabled"
    >
      <el-cascader
        :disabled="casDisabled"
        :clearable="clearable"
        ref="areaSelect"
        v-model="areaCodeList"
        :props="belongRegoinProps"
        :options="belongRegoinOptions"
        placeholder="请选择"
        @change="belongRegionChange"
        @visible-change="visibleChange"
        style="width: 100%"
      >
      </el-cascader>
    </el-tooltip>
  </div>
</template>

<script>
// 这里是我项目中自己封装的get请求 各位可自己封装
import { get } from "@/apis/apicommon";
export default {
  name: "areaCascader",
  components: {},
  // 注意:isCurrentOrgDefaultArea与isPortDefaultArea不能同时为true
  props: {
    setLevel:{
      type:Number,
      default:5
    },
    // true开启默认回显当前账号所属区划地址,为false时关闭回显并且可选择任意区划
    isCurrentOrgDefaultArea: {
      type: Boolean,
      default: true,
    },
    // 回显指定区划地址的对象数据,必须为以下指定格式字段,切且注意该对象传入时间必须在该组件初始化之前
    defaultAddressInfos: {
      type: Object,
      // default:{
      //   addressName:"",
      //   provinceCode:"",
      //   cityCode:"",
      //   countyCode:"",
      //   streetCode:"",
      //   communityCode:"",
      //   level:""
      // }
    },
    // true开启默认回显指定区划地址,需必传对象defaultAddressInfos,且与isCurrentOrgDefaultArea不能同时为true
    isPortDefaultArea: {
      type: Boolean,
      default: false,
    },
    // 是否可清空已选,默认不可清空
    clearable: {
      type: Boolean,
      default: false,
    },
    casDisabled: {
      type: Boolean,
      default:false
    },
  },
  watch: {},
  data() {
    const self = this;
    return {
      disabled: true,
      addressName: "",
      defaultHosuse: {
        province: "",
        city: "",
        area: "",
        town: "",
        vill: "",
      },
      CurrentOrg: {},
      currentLastLevelCode: "",
      CurrentLevel: Number,
      areaCodeList: [],
      currentOrgLevel: "",
      belongRegoinOptions: [],
      belongRegoinProps: {
        checkStrictly: true,
        lazy: true,
        lazyLoad(node, resolve) {
          setTimeout(() => {
            self.getAreaForLazyLoad(node, resolve);
          }, 100);
        },
      },
    };
  },
  created() {
    if (this.isCurrentOrgDefaultArea) {
      // 通过当前账号所在区划回显
      this.getCurrentOrg();
    }
    if (this.isPortDefaultArea) {
      // 通过指定区划回显
      this.getDefaultArea();
    }
  },
  methods: {
    visibleChange(val) {
      console.log(val);
      if (val) {
        this.disabled = true;
      } else if (!val && this.addressName) {
        this.disabled = false;
      }
    },
    belongRegionChange(val) {
      let res = this.$refs.areaSelect.getCheckedNodes();
      console.log(res);
      if (res && res.length > 0) {
        this.addressName =
          res[0].pathLabels[0] +
          (res[0].pathLabels[1] || "") +
          (res[0].pathLabels[2] || "") +
          (res[0].pathLabels[3] || "") +
          (res[0].pathLabels[4] || "");
        let areaNameObject = {
          provinceName: res[0].pathLabels[0],
          cityName: res[0].pathLabels[1],
          countyName: res[0].pathLabels[2],
          streetName: res[0].pathLabels[3],
          communityName: res[0].pathLabels[4],
        };
        let areaCodeObject = {
          provinceCode: res[0].path[0],
          cityCode: res[0].path[1],
          countyCode: res[0].path[2],
          streetCode: res[0].path[3],
          communityCode: res[0].path[4],
        };
        let data = {
          areaNameObject,
          areaCodeObject,
        };
        this.$emit("selectedAreaList", data);
      } else {
        this.addressName = "";
        let areaNameObject = {
          provinceName: "",
          cityName: "",
          countyName: "",
          streetName: "",
          communityName: "",
        };
        let areaCodeObject = {
          provinceCode: "",
          cityCode: "",
          countyCode: "",
          streetCode: "",
          communityCode: "",
        };
        let data = {
          areaNameObject,
          areaCodeObject,
        };
        this.$emit("selectedAreaList", data);
        this.disabled = true;
      }
    },
    getAreaForLazyLoad(node, resolve) {
      const { level } = node;
      let data = {};
      if (level == 0) {
        data = {
          areaCode: "000000",
        };
      } else if (
        level == 1 ||
        level == 2 ||
        level == 3 ||
        level == 4 ||
        level == 5
      ) {
        data = {
          areaCode: node.value,
        };
      } else {
        return false;
      }
    // 这里是接口
      get("/area/getNextAreaInfoByCode", data)
        .then((res) => {
          if (res.succeed) {
            let isContain = data.areaCode.search(this.currentLastLevelCode);
            let oData = [];
            // let oData = this.formatAreaData(res.data, level);
            if (this.isCurrentOrgDefaultArea || this.isPortDefaultArea) {
              let arrList = this.formatAreaData(res.data, level);
              arrList.map((item, index) => {
                if (
                  (item.level <= this.CurrentLevel &&
                    this.isCurrentOrgDefaultArea) ||
                  (data.areaCode !== this.currentLastLevelCode &&
                    this.CurrentLevel >= level) ||
                  isContain != 0
                ) {
                  oData.push(Object.assign({}, item, { disabled: true }));
                } else {
                  oData.push(Object.assign({}, item, { disabled: false }));
                }
              });
            } else {
              oData = this.formatAreaData(res.data, level);
            }
            // this.belongRegoinOptions = oData
            if (oData.length == 0) {
              //   // console.log('子节点数据为空', node)
              //   node.syncCheckState(node.value);
              //   const checkedNode = this.$refs.areaSelect.getCheckedNodes();
              //   // console.log('获得刚才选中的节点', checkedNode)
              //   node.syncCheckState(node.value)
              //   node.doCheck(true)
              //   this.$set(node, 'leaf', true)
              //   oData = undefined;
              //   resolve(oData);
              //   return;
            }
            resolve(oData);
          }
        })
        .catch((err) => {
          console.log(err);
          this.$message.error(err);
        });
    },
    formatAreaData(data, level) {
      return data.map((item) => {
        item.names = item.name;
        item.value = item.id;
        item.label = item.name;
        item.leaf = level >= (this.setLevel - 1);
        return item;
      });
    },
    handleAreaCode() {
      let areaCodeList = [];
      if (this.defaultHosuse.province) {
        areaCodeList.push(this.defaultHosuse.province);
        this.currentLastLevelCode = this.defaultHosuse.province;
      }
      if (this.defaultHosuse.city) {
        areaCodeList.push(this.defaultHosuse.city);
        this.currentLastLevelCode = this.defaultHosuse.city;
      }
      if (this.defaultHosuse.area) {
        areaCodeList.push(this.defaultHosuse.area);
        this.currentLastLevelCode = this.defaultHosuse.area;
      }
      if (this.defaultHosuse.town) {
        areaCodeList.push(this.defaultHosuse.town);
        this.currentLastLevelCode = this.defaultHosuse.town;
      }
      if (this.defaultHosuse.vill) {
        areaCodeList.push(this.defaultHosuse.vill);
        this.currentLastLevelCode = this.defaultHosuse.vill;
      }

      this.areaCodeList = areaCodeList;
      console.log(areaCodeList);
      if (this.addressName == "") {
        this.disabled = true;
      } else {
        this.disabled = false;
      }
    },
    getDefaultArea() {
      console.log(this.defaultAddressInfos);
      this.addressName = this.defaultAddressInfos.addressName;
      this.defaultHosuse.province = this.defaultAddressInfos.provinceCode || "";
      this.defaultHosuse.city = this.defaultAddressInfos.cityCode || "";
      this.defaultHosuse.area = this.defaultAddressInfos.countyCode || "";
      this.defaultHosuse.town = this.defaultAddressInfos.streetCode || "";
      this.defaultHosuse.vill = this.defaultAddressInfos.communityCode || "";
      this.CurrentLevel = this.defaultAddressInfos.level;
      this.handleAreaCode();
    },
    getCurrentOrg() {
      get("/organization/getCurrentOrg", {}).then((res) => {
        if (res.succeed) {
          let data = res.data;
          this.addressName =
            (data.provinceName || "") +
            (data.cityName || "") +
            (data.countyName || "") +
            (data.streetName || "") +
            (data.communityName || "");
          // this.currentOrgLevel = data.level;
          // this.CurrentOrg = data;
          // let {province='provinceCode',city='cityCode',area='countyCode',town='streetCode',vill='communityCode'} = data
          // this.defaultHosuse = {province='provinceCode',city='cityCode',area='countyCode',town='streetCode',vill='communityCode'}
          this.defaultHosuse.province = data.provinceCode;
          this.defaultHosuse.city = data.cityCode;
          this.defaultHosuse.area = data.countyCode;
          this.defaultHosuse.town = data.streetCode;
          this.defaultHosuse.vill = data.communityCode;
          this.CurrentLevel = data.level;
          this.handleAreaCode();

        let areaNameObject = {
          provinceName: data.provinceName,
          cityName: data.cityName,
          countyName: data.countyName,
          streetName: data.streetName,
          communityName: data.communityName,
        };
        let areaCodeObject = {
          provinceCode: data.provinceCode,
          cityCode: data.cityCode,
          countyCode: data.countyCode,
          streetCode: data.streetCode,
          communityCode: data.communityCode,
        };
        let val = {
          areaNameObject,
          areaCodeObject,
        };
        this.$emit("selectedAreaList", val);
        }
      });
    },
  },
};
</script>
<style scoped>
</style>
复制代码

使用文件:index.vue

复制代码
<template>
  <div>
    <el-form
      ref="tableData"
      :rules="rules"
      :model="tableData"
      label-width="130px"
      size="mini"
    >
      <el-row>
        <el-col :span="12">
          <el-form-item label="现常住地址:">
            <Area-cascader
              @selectedAreaList="selectedAreaList"
              :isCurrentOrgDefaultArea="false"
              :clearable="true"
            ></Area-cascader>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  
  </div>
</template>

<script>
import { get, downloadFile, post } from "@/apis/apicommon";
import AreaCascader from "@/components/common/areaCascader.vue";
export default {
  name: "page1",
  components: {
    AreaCascader,
  },
  props: {
    
  },
  data() {
    return {
      formData: {},
    };
  },
  created() {

  },
  mounted() {},
  methods: {
    // 地址选中值
    selectedAreaList(val) {
      // 这里是返回的区划name和code,一共有五级
      console.log(val);
      let { provinceCode, cityCode, countyCode, streetCode, communityCode } =
        val.areaCodeObject;
      this.formData.province = provinceCode;
      this.formData.city = cityCode;
      this.formData.county = countyCode;
      this.formData.street = streetCode;
      this.formData.community = communityCode;
      let { provinceName, cityName, countyName, streetName, communityName } =
        val.areaNameObject;
      this.formData.provinceName = provinceName;
      this.formData.cityName = cityName;
      this.formData.countyName = countyName;
      this.formData.streetName = streetName;
      this.formData.communityName = communityName;
    },
  
  },
};
</script>
<style scoped>

</style>
复制代码

多看一下封装的组件里面各种配置项,尤其是区划的数据格式,这里的code和name一起封装,如果有任何疑问欢迎留言!

来源:https://www.cnblogs.com/xiongcc/p/15225287.html


相关教程