vue利用级联选择器实现全国省市区乡村五级菜单联动
大家好,我是雄雄,歡迎關注微信公眾號:雄雄的小課堂。
”現在是:2022年2月13日20:09:27
今天分享一個五級級聯地址的組件的使用吧。
前言
接到這樣的一個需求:需要根據地址查詢列表信息,地址可以分別按照省、市、縣、鄉、村 五級作為條件查詢。
如果但是這個需求還好說,以前使用的方式是放五個下拉列表,通過懶加載的方式,根據省得到該省下的市,根據市得到該市下的縣……最后可以得到村的級別,然后作為條件查詢,也就是下面的這種方式:
image-20220213201630629image-20220213201641535但是,客戶說,太長了……因為他的另一個需求是這樣的:
image-20220213203322417如果放5個的話,就會造成裝不下的bug。
image-20220213203822894實現思路
原來采用的是select,現在看來,select顯然不是最好的解決方式,去element-ui上面看了看,發現了另一個組件:Cascader 級聯選擇器,樣式如下:
image-20220213204120997于是就把這個Cascader 組件改了改,改成了省市區鄉村的組件,同時也做成了公共組件,項目中可以多次共用。
數據表結構
全國省市區鄉村沒有使用json的方式,將所有的省市區鄉村信息都放在了數據庫中,用的時候根據父級編號查詢,數據庫表結構如下:
image-20220213204531326級聯實現地址聯動
實現思路:頁面初次加載的時候,將全國所有省查詢出來,封裝放在級聯組件Cascader中,當用戶選擇某個省的時候,將當前省的編碼作為父級編碼,去查詢所有的市。比如選的山東省,查詢出來的就是山東所有市,濟南,聊城,菏澤等。
為了解決系統性能問題,我將查詢出來的信息都放在了redis緩存中了,緩存里面沒有的話去數據庫里面找去,有則在緩存中取,效率要高點兒。
下面是公共組件中的代碼:
<!--作者:mxx時間:2022年2月11日16:22:07描述:el-Cascader實現省市區鄉村菜單 --> <template><div><div class="block"><el-cascaderv-model="selectedOptions":show-all-levels="false"ref="sysCascader":size="size":placeholder="placeholder":props="props"@change="handleChange"clearable></el-cascader></div><!-- 鼠標懸浮觸發 --> <!-- <div class="block"><span class="demonstration">hover 觸發子菜單</span><el-cascaderexpand-trigger="hover":options="options"v-model="selectedOptions2"@change="handleChange"></el-cascader></div>--></div> </template><script> import {listArea} from "../../../api/system/area"; export default {name: "addressCommonComponentsUtils",props: {//組件大小size: {type: String,default: "mini"},//組件的提示信息placeholder: {type: String,default: "請選擇地區"}},data() {let self = this;return {/*省市區的集合*/options: [],props: {lazy: true,checkStrictly: true,lazyLoad: this.getLazyLoad,},selectedOptions: [],// 地址查詢參數qParams: {pid: null,type: null,},//省市區的值addressInfo: {//編碼//省sonProvinceValue: null,//市sonCityValue: null,//區sonAreaValue: null,//街道sonStreetValue: null,//鄉村sonCountryValue: null,//名字//省sonProvinceName: null,//市sonCityName: null,//區sonAreaName: null,//街道sonStreetName: null,//鄉村sonCountryName: null,},};},created() {},methods: {//懶加載省份信息到組件中getLazyLoad(node, resolve) {setTimeout(() => {if (node.level == 0) {this.qParams.type = 1;listArea(this.qParams).then(res => {const cities = res.rows.map((value, i) => ({value: value.areaId,label: value.name,leaf: node.level >= 2,}));// 通過調用resolve將子節點數據返回,通知組件數據加載完成resolve(cities);}).catch(err => {console.log(err);});}if (node.level != 0 && node.level < 5) {this.qParams.type = node.level + 1;this.qParams.pid = node.value;listArea(this.qParams).then(res => {const areas = res.rows.map((value, i) => ({value: value.areaId,label: value.name,leaf: node.level >= 4}));//設置省市區街村的值this.setNameAndValue(node);// 通過調用resolve將子節點數據返回,通知組件數據加載完成resolve(areas);}).catch(err => {console.log(err);});} else if (node.level == 5) {//最后一個節點,不去查詢了,直接賦值const areas = {value: node.value,label: node.label,leaf: node.level};//將值和名稱賦值到變量里面this.addressInfo.sonCountryValue = node.value;this.addressInfo.sonCountryName = node.label;resolve(areas);}}, 10);},//通過當前選擇的地區,設置到對應的變量中setNameAndValue(node) {switch (node.level) {case 1:this.addressInfo.sonProvinceValue = node.value;this.addressInfo.sonProvinceName = node.label;this.addressInfo.sonCityValue = null;this.addressInfo.sonCityName = null;this.addressInfo.sonAreaValue = null;this.addressInfo.sonAreaName = null;this.addressInfo.sonStreetValue = null;this.addressInfo.sonStreetName = null;this.addressInfo.sonCountryValue = null;this.addressInfo.sonCountryName = null;break;case 2:this.addressInfo.sonCityValue = node.value;this.addressInfo.sonCityName = node.label;this.addressInfo.sonAreaValue = null;this.addressInfo.sonAreaName = null;this.addressInfo.sonStreetValue = null;this.addressInfo.sonStreetName = null;this.addressInfo.sonCountryValue = null;this.addressInfo.sonCountryName = null;break;case 3:this.addressInfo.sonAreaValue = node.value;this.addressInfo.sonAreaName = node.label;this.addressInfo.sonStreetValue = null;this.addressInfo.sonStreetName = null;this.addressInfo.sonCountryValue = null;this.addressInfo.sonCountryName = null;break;case 4:this.addressInfo.sonStreetValue = node.value;this.addressInfo.sonStreetName = node.label;this.addressInfo.sonCountryValue = null;this.addressInfo.sonCountryName = null;break;case 5:this.addressInfo.sonCountryValue = node.value;this.addressInfo.sonCountryName = node.label;break;}},/*改變事件*/handleChange(event) {let node = this.$refs.sysCascader.getCheckedNodes()[0];//解決不點字 只點擊單選按鈕的問題this.setNameAndValue(node);//將該組件中的值傳遞給父組件//getCheckedAddressInfo: 是父組件指定的傳數據綁定的函數,this.$emit('getCheckedAddressInfo', this.addressInfo)},} } </script><style scoped></style>關鍵代碼都有相應的注釋,應該看起來都沒有問題。
或許有些地方的代碼冗余,但是我沒法再優化了……這個組件大致的功能就是將用戶選擇的地址信息,傳遞到父組件中,父組件通過getCheckedAddressInfo函數拿到用戶選擇的地址信息,不管選擇哪一級都可以,最后在根據地址信息做其他操作。
listArea方法:根據條件查詢地址信息,傳遞的參數是地址實體,在本文的最后我附上后臺的實現代碼。
級聯地址組件的使用
使用方法也很簡單,只需這么幾步:
1.先導入組件:
import?addressCommonComponentsUtils?from?"../area/addressCommonComponentsUtils";2.注冊組件:
在export default 里面寫如下代碼:
components:?{"address-utils":?addressCommonComponentsUtils,},image-202202132123227063.在template中引入級聯地址組件:
<address-utils:size="mini":placeholder="checkdiqu"@getCheckedAddressInfo="getCheckedAddressInfo"></address-utils>4.在methods中寫getCheckedAddressInfo方法回去選擇的地址信息:
//獲取用戶選擇的地址信息getCheckedAddressInfo(value){//給地址欄中賦值this.queryParams.fieldProvince?=?value.sonProvinceName;this.queryParams.fieldCity?=?value.sonCityName;this.queryParams.fieldArea?=?value.sonAreaName;this.queryParams.fieldStreet?=?value.sonStreetName;this.queryParams.fieldCommunity?=?value.sonCountryName;},參數說明:
編碼:比如北京是110000,山西是:140000等
//省 `sonProvinceValue,
//市 `sonCityValue,
//區 `sonAreaValue,
//街道 `sonStreetValue,
//鄉村 `sonCountryValue,
名字:比如北京是**【北京】,山西是【山西省】**
//省 sonProvinceName,
//市 `sonCityName,
//區 `sonAreaName,
//街道 `sonStreetName,
//鄉村 sonCountryName,
最后實現的效果如下:
image-20220213213301547附:后臺查詢地址的代碼
area.js:
//?查詢地址列表 export?function?listArea(query)?{return?request({url:?'/system/area/list',method:?'get',params:?query}) }SysAreaController中的代碼:
@Autowiredprivate?ISysAreaService?sysAreaService;/***?查詢地址列表*///@PreAuthorize("@ss.hasPermi('system:area:list')")@GetMapping("/list")public?TableDataInfo?list(SysArea?sysArea){//?startPage();List<SysArea>?list?=?sysAreaService.selectSysAreaList(sysArea);return?getDataTable(list);}SysAreaServiceImpl中的代碼:
@Autowiredprivate?SysAreaMapper?sysAreaMapper;@Autowiredprivate?RedisCache?redisCache;/***?查詢地址*?*?@param?id?地址主鍵*?@return?地址*/@Overridepublic?SysArea?selectSysAreaById(Long?id){return?sysAreaMapper.selectSysAreaById(id);}/***?查詢地址列表*?*?@param?sysArea?地址*?@return?地址*/@Overridepublic?List<SysArea>?selectSysAreaList(SysArea?sysArea)?{//分批次判斷地址List<SysArea>?areaList?=?new?ArrayList<>();//地址對象SysArea?area?=?new?SysArea();if(sysArea.getPid()==null){sysArea.setPid("100000");}//市、區縣、街道、村if?(redisCache.getCacheList(sysArea.getPid()?+?"ListCache").size()==0)?{System.out.println("=========================走數據庫了=========================");area.setType(sysArea.getType());//將父級編號放進來area.setPid(sysArea.getPid());areaList?=?sysAreaMapper.selectSysAreaList(area);redisCache.setCacheList(sysArea.getPid()?+?"ListCache",?areaList);}?else?{System.out.println("=========================走緩存了=========================");//從緩存中取出來areaList?=?redisCache.getCacheList(sysArea.getPid()?+?"ListCache");}return?areaList;}Mapper層和Service的接口層就不放了,就正常寫,返回集合就行:
/***?查詢地址列表*?*?@param?sysArea?地址*?@return?地址集合*/public?List<SysArea>?selectSysAreaList(SysArea?sysArea);最后是mapper.xml中的sql:
<sql?id="selectSysAreaVo">select?id,?name,?area_id,?pid,?type,?status,?del_flag,?create_time,?update_time,?pids,?m_pid,?m_pids,?m_type,?region,?remark?from?sys_area</sql><select?id="selectSysAreaList"?parameterType="SysArea"?resultMap="SysAreaResult"><include?refid="selectSysAreaVo"/><where><if?test="name?!=?null??and?name?!=?''">?and?name?like?concat('%',?#{name},?'%')</if><if?test="areaId?!=?null??and?areaId?!=?''">?and?area_id?=?#{areaId}</if><if?test="pid?!=?null??and?pid?!=?''">?and?pid?=?#{pid}</if><if?test="type?!=?null?">?and?type?=?#{type}</if><if?test="status?!=?null?">?and?status?=?#{status}</if><if?test="pids?!=?null??and?pids?!=?''">?and?pids?=?#{pids}</if><if?test="mPid?!=?null??and?mPid?!=?''">?and?m_pid?=?#{mPid}</if><if?test="mPids?!=?null??and?mPids?!=?''">?and?m_pids?=?#{mPids}</if><if?test="mType?!=?null?">?and?m_type?=?#{mType}</if><if?test="region?!=?null??and?region?!=?''">?and?region?=?#{region}</if></where></select>總結
好了,今天分享的就這些了,源碼也都貼上來啦,記錄記錄,一來或許可以幫助大家,二來自己以后用的時候,也可以直接上來扒代碼了。
下一篇:springboot解析word文檔,包括復雜的圖片,復選框等。
問:你知道CV工程師是啥嗎?
總結
以上是生活随笔為你收集整理的vue利用级联选择器实现全国省市区乡村五级菜单联动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel函数大全excel函数大全完整
- 下一篇: 赏云协会,和它的59000多个会员