本文需要的前置知识点SpringBoot+mybatisPlus+vue
最终效果如下图所示
1.新建一个springboot项目引入mybatis-plus 并且使用脚手架搭建一个Vue项目,在Vue项目中引入ElementUI以及Axios,在mysql创建相关数据库
相关表结构如下
后端boot项目结构如下
三级联动的关键在于每一级的变动都会对一下的子级产生影响,一旦当前级的内容更改,下一级的内容要立刻随之更改;
前端页面主要代码如下
<template>
<div>
省份:<el-select v-model="provinceCode" placeholder="请选择" @change="provinceChange">
<el-option
v-for="item in provinces"
:key="item.id"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
城市:<el-select v-model="cityCode" placeholder="请选择" @change="cityChange">
<el-option
v-for="item in citys"
:key="item.id"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
区域:<el-select v-model="townCode" placeholder="请选择">
<el-option
v-for="item in towns"
:key="item.id"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
</div>
</template>
<script>
export default {
name: "CityMain",
data(){
return{
URL:'http://localhost:8080',
provinces:[],
citys:[],
towns:[],
provinceCode:'',
cityCode:'',
townCode:'',
province:{id:'',name:'',code:''},
flag:false,
addOrUpdate:'',
}
},
methods:{
//默认加载根节点
initProvince(){
this.$axios({
url:this.URL+"/province",
method:'get'
}).then(re=>{
this.provinces=re.data
console.log(re.data)
})
},
//一级菜单变化时
provinceChange(){
this.cityCode=''
this.townCode=''
this.$axios({
url:this.URL+"/city/"+this.provinceCode,
method:'get'
}).then(re=>{
this.citys=re.data
console.log(re.data)
})
},
//二级变化时
cityChange(){
this.townCode=''
this.$axios({
url:this.URL+"/town/"+this.cityCode,
method:'get'
}).then(re=>{
this.towns=re.data
console.log(re.data)
})
},
},
created() {
this.initProvince();
}
}
</script>
<style scoped>
</style>
所以我们可以开始默认加载根节点,绑定seleect框,并且绑定change事件,一旦当前节点的值发生变化,则子节点内容重新根据当前节点数据请求后台数据并且进行绑定
@RestController
@CrossOrigin
@RequestMapping("/province")
public class ProvinceController {
@Autowired
private TAddressProvinceMapper mapper;
@GetMapping
public List<TAddressProvince> getAllProvince(){
return mapper.selectList(null);
}
}
然后编写市级所对应的Controller 以及区级所对应的Controller
@RestController
@CrossOrigin
@RequestMapping("/city")
public class CityController {
@Autowired
private TAddressCityMapper mapper;
@GetMapping("/{provincecode}")
public List<TAddressCity> getCityByProvincecode(@PathVariable("provincecode")String provincecode){
LambdaQueryWrapper<TAddressCity> wrapper=new LambdaQueryWrapper<>();
wrapper.eq(TAddressCity::getProvincecode,provincecode);
return mapper.selectList(wrapper);
}
}
@RestController
@CrossOrigin
@RequestMapping("/town")
public class TownController {
@Autowired
private TAddressTownMapper mapper;
@GetMapping("/{citycode}")
public List<TAddressTown> getTownWithCityCode(@PathVariable("citycode")String citycode){
LambdaQueryWrapper<TAddressTown> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.eq(TAddressTown::getCitycode,citycode);
return mapper.selectList(queryWrapper);
}
}
搜索市的时候按照省级节点提供的省级编码,搜索区的时候按照市级节点提供的城市编码,在前端相对应的节点上都绑定上change事件,就可以完成三级联动的效果了
最后的对应的实体类
@Data
public class TAddressCity {
private Integer id;
//城市编码
private String code;
//城市名称
private String name;
//所属省份编码
private String provincecode;
}
@Data
public class TAddressProvince {
private Integer id;
//省份编码
private String code;
//省份名称
private String name;
}
@Data
public class TAddressTown {
private Integer id;
//区县编码
private String code;
//区县名称
private String name;
//所属城市编码
private String citycode;
}