可回显、接口懒加载 基于elementUI的Cascader组件封装的多功能地区区划选择器

注:公司领导要求封装一个区划选择器,最大支持五级区划,并且适用的场景有很多:数据全部由接口所得并且是懒加载形式;能够回显当前登录账号所属级别的默认地址;还能够回显接口返回的默认地址;能够配置区划选择器的最大级别;禁止当前级别之前的地址被选择等等功能,花了两天的事时间,终于算是完善优化好了,供大家一起参考,代码若有缺陷还望指针,感谢!以下是源代码:
【可回显、接口懒加载 基于elementUI的Cascader组件封装的多功能地区区划选择器】特别说明:这里面使用懒加载形式调取接口,每次接口返回一个级别的数据,如第一次默认返回所有省级,点击安徽省,传安徽省code则再次调用接口返回安徽省下所有地级市的数据,依次类推;这里接口返回的数组中,必须要有的参数:[{name:'级别名称',id:'级别code值'}]
技术栈:VUE+ElementUI
组件areaCascader.vue
<template><div><el-tooltipeffect="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不能同时为trueprops: {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不能同时为trueisPortDefaultArea: {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 = https://tazarkount.com/read/{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 = https://tazarkount.com/read/{areaNameObject,areaCodeObject,};this.$emit("selectedAreaList", data);this.disabled = true;}},getAreaForLazyLoad(node, resolve) {const { level } = node;let data = https://tazarkount.com/read/{};if (level == 0) {data = {areaCode:"000000",};} else if (level == 1 ||level == 2 ||level == 3 ||level == 4 ||level == 5) {data = https://tazarkount.com/read/{areaCode: node.value,};} else {return false;}
// 这里是接口get("/area/getNextAreaInfoByCode", data).then((res) => {if (res.succeed) {let isContain = data.areaCode.search(this.currentLastLevelCode);let oData = https://tazarkount.com/read/[];// 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 = oDataif (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 = https://tazarkount.com/read/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 = https://tazarkount.com/read/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-formref="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一起封装,如果有任何疑问欢迎留言!