需求:1、不要一次引入全部数据,加载过慢;2、传入数据要回显;3、暂不增加后端接口
一、首先找到全国的省市区镇信息,但是不能一次性引入,需要分开
找了很久最后发现了这个宝藏划区 (按照等级划分,起名为各个区域标号)GitHub - lizeze/china_region: 行政区域数据, 包括省,市,区,县,镇,街道
将左边的数据1-4换了名字为province、city、district、street,可以不换,看个人偏好。
可直接下载已修改过的。
二、直接封装组件
1、懒加载
2、数据回显
直接上代码:
<template>
<div class="cascaderArea">
<el-cascader
v-if="showCascader"
:props="props"
:options="nowData"
v-model="selectedOptions"
placeholder="请选择区域"
@change="handleChange"
style="width: 100%"
></el-cascader>
</div>
</template>
<script>
export default {
name: 'cascaderArea',
props: ['Address'],
watch: {
Address: {
deep: true,
immediate: true,
handler(newVal,oldVal) {
if(newVal && newVal.length > 0){
this.selectedOptions = newVal;
this.setArea(this.selectedOptions)
}
}
},
},
data() {
return {
showCascader: true,
selectedOptions: this.Address,
type: ['province','city','district','street'],
nowData: [],
props: {
lazy: true,
lazyLoad: (node, resolve) => {
const { level, children } = node;
// 防止数据重复加载
if (children && children.length > 0) return resolve(nodes)
const nodes = [];
let id = level === 0 ? '100000' : node.data.id;
let realData = require(`../assets/json/city_data/${this.type[level]}/${id}.json`);
realData.map((item) => {
let area = {
value: item.name,
label: item.name,
leaf: node.level >= 3,
id: item.adcode,
};
nodes.push(area)
})
resolve(nodes)
},
}
}
},
methods: {
// 数据回显
setArea(arr) {
this.showCascader = false;
this.nowData = []
let optionsList = [];
let realList = [];
for (let i=0; i < arr.length; i++) {
let id = i === 0 ? '100000' : realList[i-1].id;
let realData = require(`../assets/json/city_data/${this.type[i]}/${id}.json`);
for (let j=0; j < realData.length; j++) {
let area = {
value: realData[j].name,
label: realData[j].name,
leaf: i >= 3,
id: realData[j].adcode,
};
if (i === 0) {
optionsList.push(area)
}else if (i === 1){
optionsList[realList[0].index].children.push(area)
}else if (i === 2){
optionsList[realList[0].index].children[realList[1].index].children.push(area)
}else if (i === 3){
optionsList[realList[0].index].children[realList[1].index].children[realList[2].index].children.push(area)
}
if(realData[j].name === arr[i]){
area.index = j;
area.children = [];
realList.push(area)
}
}
}
this.nowData = optionsList;
this.$nextTick(() => {
this.showCascader = true;
})
},
handleChange(value) {
this.$emit('city', value)
},
}
}
</script>
<style lang="scss" scoped>
</style>
这其中还有一些可以优化的地方,但是大致思路就是这些了,如果后续增加接口,直接将请求本地资源换位请求接口即可。