先看最终实现效果图。
需求描述
根据城市,加载区县,根据选中区县加载对应街道。选中区或街道后在高德地图上展示。
问题描述
设置显示的时候没有什么问题。 但是在编辑回显时,若选择了区级的下级街道,el-cascader无法填充对应的值(一片空白。。。)。 比如如上图,我若设置显示 上海 浦东新区/宣桥镇,el-cascader无法设置;但是我若设置 上海 浦东新区是没有问题的。
我猜测可能是由于el-cascader设置了延迟加载,没有触发对应区县,所以无法加载区县级下面的街道。
解决
若当前设置区县级下面的街道时,手动点击区县,让el-cascader实现自动请求加载。但是设置时会有1s左右延迟,如上图。
贴一下关键代码。希望有类似需求的同学可以一起讨论,也希望感兴趣的大佬不吝赐教。
<template>
<div>
<el-cascader :options="cascaderOpt" v-model="district" :key="cascaderKey" ref="cascaderOptDis"
v-if="show" style="width:100%"
clearable placeholder="请选择" :props="props"
popper-class="cascader-district"
@change="districtChange"></el-cascader>
</div>
</template>
<script>
let disListOpts = {
subdistrict: 1, //返回下一级行政区
showbiz: true, //最后一级返回街道信息
extensions: 'all',
level: 'city'
};
let disList = null
// import _ from 'lodash'
import AMap from 'AMap'
export default {
data() {
return {
// 手动输入地址进行关联
district: [],
cascaderOpt: [],
cascaderKey: 1,
show: true,
props: {
lazy: true,
checkStrictly: true,
// expandTrigger: 'hover',
lazyLoad: (node, resolve) => {
if (!disList) {
disList= new AMap.DistrictSearch(disListOpts);
}
if (node && node.level) {
disList.setLevel('district')
disList.search(node.value, (status, result) => {
if(status === 'complete'){
// let districtList = result.districtList[result.districtList.length - 1].districtList
let districtList = []
if (result.districtList.length > 1) {
for(let i = 1; i < result.districtList.length; i++) {
districtList = districtList.concat(result.districtList[i].districtList)
}
} else {
districtList = result.districtList[0].districtList
}
if (!districtList || !districtList.length) {
resolve([]);
return
}
const nodes = districtList
.map(item => ({
value: item.name,
adcode: item.adcode,
label: item.name,
level: item.level,
center: item.center,
boundaries: result.districtList[result.districtList.length - 1].boundaries,
leaf: true
}));
// 通过调用resolve将子节点数据返回,通知组件数据加载完成
resolve(nodes);
}
});
}
}
},
}
},
watch: {
// 若时新增关联到达区域城市id
'district': {
handler: function (val) {
if (val) {
this.$refs.cascaderOptDis.dropDownVisible = false;
}
},
deep: true
},
},
methods: {
clear() {
this.district = []
},
changeValue(arr) {
setTimeout(() => {
this.$nextTick(() => {
this.district = arr;
})
},1000)
},
districtChange() {
let nodes = this.$refs.cascaderOptDis.getCheckedNodes()
console.log(nodes)
if (nodes&& nodes[0] && nodes[0].data) {
this.$emit('change:district',nodes[0].data,this.district)
}
},
initDistrict(cityName,arr) {
if (!cityName) {
return
}
//行政区划查询
this.cascaderKey ++
disList= new AMap.DistrictSearch(disListOpts);
disList.search(cityName, (status, result) => {
if(status === 'complete'&&result.districtList[result.districtList.length - 1].districtList&&result.districtList[result.districtList.length - 1].districtList.length){
let districtList = []
if (result.districtList.length > 1) {
for(let i = 1; i < result.districtList.length; i++) {
districtList = districtList.concat(result.districtList[i].districtList)
}
} else {
districtList = result.districtList[0].districtList
}
this.cascaderOpt = districtList
.map(item => ({
value: item.name,
adcode: item.adcode,
label: item.name,
// level: item.level,
center: item.center,
leaf: false
}));
// 通过调用resolve将子节点数据返回,通知组件数据加载完成
// 还需要加载街道
console.log(arr)
if (arr && arr.length > 1) {
this.$nextTick(() => {
// this.district = arr
document.querySelectorAll(".el-cascader-node__label").forEach(el => {
if (el.innerHTML === arr[0]) {
el.click()
this.$refs.cascaderOptDis.dropDownVisible = false;
this.changeValue(arr)
}
});
})
} else {
this.district = arr || [];
}
}
});
},
}
};
</script>
<style lang="scss">
@import '@/scss/_handle.scss';
.position-search {
position: relative;
.address_items {
position: absolute;
z-index: 10;
max-height: 300px;
border: solid 1px #E4E7ED;
border-radius: 4px;
background: #fff;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
min-width: 410px;
.address_item {
display: flex;
width: 100%;
margin-top: 6px;
&:hover {
background-color: #F5F7FA;
cursor: pointer;
}
.address_item_icon {
@include font_color("color-primary");
font-size: 15px;
margin-right: 6px;
margin-left: 15px;
width: 20px;
line-height: 22px;
align-self: flex-start;
}
.address_item_word {
flex: 1;
.title {
line-height: 20px;
font-size: 14px;
text-overflow: ellipsis;
white-space: nowrap;
@include font_color("color-primary");
}
.description {
font-size: 12px;
color: #9DA3AA;
text-overflow: ellipsis;
// white-space: nowrap;
overflow: hidden;
line-height: 17px;
}
}
}
.address_empty {
padding-left: 15px;
line-height: 30px;
font-size: 12px;
}
}
}
</style>