jeecgboot自带省市区组件,但是我们的需求是输入户籍,一般来说户籍只需要输入省和市即可,所以jeecgboot自带的省市区组件不适用。
实现思路:
放两个select,第一个是省,第二个是市,市的option要由选择的省来确定,两者由联动关系。
实现步骤:
1、数据库分三个字段,province(省),city(市)和register(户籍),省和市存code,户籍存文本,根据省市code对应的文本进行拼接即可得到户。在表单页只显示province和city字段,客户下拉输入,在查询页只显示register字段,显示户籍的文本内容,比如湖北省武汉市。
2、jeecgboot自带china-area-data插件,我们只需要在组件vue文件里引入即可。
如果大家项目上没有这个插件,就用yarn安装一下。
3、mounted里我们就要从china-area-data里获取provinces,作为省的下拉框数据源,需要特别注意的是,a-select的数据源中每个元素最好具有value和label这种格式,生成option的时候就不需要做字段替换了。
4、在选择了省之后,也就是省的下拉框触发了change事件后,我们需要设置市的下拉选项了,getCity和getProvince方法类似,但是我不太会用递归,所以还是分开写两个方法。
并且此时我们把选择的省code和省name存在变量里,code要存进数据库,name要拼接户籍文本。
5、选择了市之后,同样要保存市的code和name,然后把省和市的name拼接成户籍,保存起来,省市code和户籍文本,三个数据存在data变量里,我们通过自定义组件的change事件,把组件输出的结果传递给父组件,好让父组件保存到数据库里。
6、组件开发完成了,然后到父组件里使用子组件,父组件给子组件传入省市code(code在父组件页面加载的时候通过接口获取),如果是编辑记录,name子组件会根据传入的省市code来反显文本,总结一下就是父组件通过自定义属性(props)传值给子组件,而子组件通过自定义事件传值给父组件,这样父子组件就可以互通有无了。
自定义组件源码:
<template>
<!-- 自定义组件:户籍下拉选择 -->
<div>
<a-select :default-value="province" placeholder="请选择省" :options="provinces" @change="handleChange">
</a-select>
<a-select :default-value="city" placeholder="请选择市" :options="cities" @change="handleChange2">
</a-select>
</div>
</template>
<script>
import pcaa from 'china-area-data';
export default {
name: "register",
props: {
province:{
type: String,
},
city:{
type: String,
}
},
components: {},
data() {
return {
provinces:[],
cities:[],
provinceCode:'',//选中省的代码
cityCode:'',//选中省的代码
provinceName:'',//选中的市的名字
cityName:'',//选中的市的名字
}
},
created() {},
mounted() {
this.provinces = this.getProvince();
// 如果是从数据库反显省市,需要对市的下拉框特殊处理。
// 如果省不为空,表示从数据库获取了数据,需要将省和市的下拉选项做联动
if(this.province){
this.cities = this.getCity(this.province);
}
},
methods: {
// 根据选择的省,更新市的下拉选项
handleChange(value){
this.cities = this.getCity(value);
this.provinceCode = value;
// 根据code获取name
let index = this.provinces.findIndex(item=>item.value==value);
this.provinceName = this.provinces[index].label;
},
// 选择市
handleChange2(value){
// 将省市拼接放在籍贯字段里
this.cityCode = value;
let index = this.cities.findIndex(item=>item.value==value);
this.cityName = this.cities[index].label;
let origin = this.provinceName+this.cityName;
// 将省市和拼接后的籍贯作为对象传给父组件
let data = {
province:this.provinceCode,
city:this.cityCode,
origin:origin
}
this.$emit('change', data);
},
getProvince() {
let arr = []
const province = pcaa['86']
Object.keys(province).map(key => {
arr.push({
value: key,
label: province[key],
});
})
return arr;
},
// 获取市
getCity(province) {
let arr = []
const city = pcaa[province]
Object.keys(city).map(key => {
arr.push({
value: key,
label: city[key],
});
})
return arr;
}
}
}
</script>
<style scoped>
</style>
父组件直接使用子组件即可,唯一需要注意的是要给子组件加上change事件,在事件里拿到子组件的输出数据,以供父组件使用。
最终效果: