VUE实现公用组件省市区三级下拉联动的过程
由于很久没有更新博客和公众号了,找了点以前的资源,暂时发一下更新
准备js接口
import request from '@/router/axios';
//获取省份
export const getProvinceDict = () => {
return request({
url: '/api/blade-system/canton/getProvince',
method: 'get',
params: {
}
});
}
//获取城市
export const getCityDict = (province) => {
return request({
url: '/api/blade-system/canton/getCity',
method: 'get',
params: {
province
}
});
}
//获取地区
export const getAreaDict = (city) => {
return request({
url: '/api/blade-system/canton/getArea',
method: 'get',
params: {
city
}
});
}
vue文件
定义好模版,参考element-ui的语法,完成3级联动,第一步很简单,难点主要在返回值和默认值
返回值的重点在于 this.$emit的使用。
callback(){
this.$emit("ChangeValue",{province:this.province,city:this.city,area:this.area});
}
客户端需要提供ChangeValue方法来回调,得到最终的返回值。
<avue-form ref="optionForm" v-model="regForm" :option="optionprops" :inline="true">
<template slot-scope="scope" slot="address">
<provincial-cascade @ChangeValue="GetProvinceValue" provinceCode="430000" cityCode="430100" areaCode="430102"></provincial-cascade>
</template>
</avue-form>
GetProvinceValue(item){
// console.log(item);
var provinceCode=item.province;
var cityCode=item.city;
var areaCode=item.area;
}
对于默认值,不能直接传给对应的province、city、area,而要传递给另一个变量作为副本。 在load的过程中,如果发现默认值不为空,则手动触发(调用)一下change方法,最终达到回显的效果。
provinceCode:"",
cityCode:"",
areaCode:"",
if(this.provinceCode!=null)
{
this.changeProvince(this.provinceCode);
}
if(this.cityCode!=null)
{
this.changeCity(this.cityCode);
}
if(this.areaCode!=null)
{
this.changeArea(this.areaCode);
}
完整代码
<template>
<el-row >
<el-col :span="8">
<el-select v-model="this.province" clearable @change="changeProvince">
<el-option
v-for="item in this.provinceData"
:key="item.key"
:label="item.name"
:value="item.key">
</el-option>
</el-select>
</el-col>
<el-col :span="8">
<el-select v-model="this.city" clearable @change="changeCity">
<el-option
v-for="item in this.cityData"
:key="item.key"
:label="item.name"
:value="item.key">
</el-option>
</el-select>
</el-col>
<el-col :span="8">
<el-select v-model="this.area" clearable @change="changeArea">
<el-option
v-for="item in this.areaData"
:key="item.key"
:label="item.name"
:value="item.key">
</el-option>
</el-select>
</el-col>
</el-row>
</template>
<script>
import {getProvinceDict,getCityDict,getAreaDict} from '@/api/util/provincialCascade';
export default {
props:["provinceCode","cityCode","areaCode"],
name: "provincial-cascade",
data(){
return {
provinceCode:"",
cityCode:"",
areaCode:"",
province:"",
city:"",
area:"",
provinceData:[],
cityData:[],
areaData:[]
}
},
created(){
},
beforeMount(){
this.loadProvince();
},
methods:{
loadProvince(){
getProvinceDict().then((res)=>{
this.provinceData=res.data.data;
if(this.provinceCode!=null)
{
this.changeProvince(this.provinceCode);
}
})
},
changeProvince(v){
getCityDict(v).then(res=>{
this.cityData=res.data.data;
this.province=v;
this.city="";
this.area="";
if(this.cityCode!=null)
{
this.changeCity(this.cityCode);
}
this.callback();
})
},
changeCity(v){
getAreaDict(v).then(res=>{
this.areaData=res.data.data;
this.city=v;
this.area="";
if(this.areaCode!=null)
{
this.changeArea(this.areaCode);
}
this.callback();
})
},
changeArea(v){
this.area=v;
// this.$emit("getValue",{provice:this.provice,city:this.city,area:this.area})
this.callback();
},
callback(){
this.$emit("ChangeValue",{province:this.province,city:this.city,area:this.area});
}
}
}
</script>
<style scoped>
</style>
后端接口
后台用的BLADEX框架,公司已经买了永久授权了。当然大家如果感兴趣的话,可以去找BLADEX源码(https://bladex.cn/#/)去学习研究,也可以做一下这几个后台接口,试一下代码效果。 后台接口按照字典格式返回数据,基本上就没问题的。
接口地址:
/api/blade-system/canton/getProvince
/api/blade-system/canton/getCity
/api/blade-system/canton/getArea
更多方法
这个是我2020年的笔记,记录的一种方式,时间过去也有三四年了,可能技术发生了很多变化,如果大家有更好的方式和方法,也可以介绍给我学习一下,欢迎大家多多交流更多的技术方法。