当前位置:
首页 > 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
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数