省市区三级联动功能实现(前端+后端)

一.后端部分

1.建表存放省市区三级数据

DROP TABLE IF EXISTS `ldaddress`;
CREATE TABLE `ldaddress`  (
                              `PLACETYPE` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '地域类型 ',
                              `PLACECODE` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '地域代码 ',
                              `PLACENAME` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '地域名称 ',
                              `UPPLACENAME` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '上级地域代码 ',
                              `ZIPCODE` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '邮编',
                              PRIMARY KEY (`PLACETYPE`, `PLACECODE`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Compact;

2.插入省市区数据

其中,placetype表示省市区标记,分别用01,02,03表示.

placecode表示省市区编码

upplacename表示市区上一级的编码

3.建立三个类存放查出来的市区级数据

1)存放基本信息的类EnumVO

@Data
public class EnumVO {
    private String name;
    private String type;
}

2)存放区县数据的类CountryVO

@Data
public class CountryVO {
    private String type;
    private String name;
    private List countryArr;
}

其中,countryArr集合存放的就是查询出来的一个个区县,type和name分别存放某一个市的信息

3)存放市级数据的类CityVO

@Data
public class CityVO {
    private String type;
    private String name;
    private List cityArr;
}

原理同上

4.开始全量查询省市区三级信息

1)Mapper层

       

2)调用mapper查询省市区数据

public List getAddress(){
        List provinceArr = new ArrayList<>();
        // 先查询出省
        List provinces = ldAddressMapper.getByPlaceType("01");
        for (LdAddress province : provinces) {
            // 根据省查询市的信息
            List cities = ldAddressMapper.getByPrimaryKey("02", province.getPlaceCode());
            CityVO cityVO = new CityVO();
            List countryVOS = new ArrayList<>();
            for (LdAddress city : cities) {
                List countries = ldAddressMapper.getByPrimaryKey("03", city.getPlaceCode());
                CountryVO countryVO = new CountryVO();
                List enumVOS = new ArrayList<>();
                // 一个市对应的多少个区countryArr集合
                for (LdAddress country : countries) {
                    EnumVO enumVO = new EnumVO();
                    enumVO.setType(country.getPlaceCode());
                    enumVO.setName(country.getPlaceName());
                    enumVOS.add(enumVO);
                }
                countryVO.setCountryArr(enumVOS);
                countryVO.setType(city.getPlaceCode());
                countryVO.setName(city.getPlaceName());
                countryVOS.add(countryVO);
            }
            cityVO.setCityArr(countryVOS);
            cityVO.setType(province.getPlaceCode());
            cityVO.setName(province.getPlaceName());
            provinceArr.add(cityVO);
        }
        return provinceArr;
    }

5.Controller层返回查询到的数据

@RestController
@RequestMapping("code")
public class CodeController {
    @Autowired
    private CodeService codeService;
    /**
     * 获取枚举值
     */
    @GetMapping("getEnums")
    public JsonResult getEnums(){
        return JsonResult.ok(codeService.getAddress());
    }
} 

二.前端部分

1.使用vue框架以及ElementUI建立一个下拉框

      -      -      

该下拉框包含在表单中,表单部分不赘述.

2.写javaScript语句

1)获取后端传值

getCode() {
            let url = "http://localhost:8888/code/getEnums";
            this.axios.get(url).then(response => {
                let codeVO = response.data.data;
                this.provinceArr = codeVO.provinceArr;
            })
        },

我是封装在了codeVO里面传递给前端的,所以我接受数据的时候使用了相同的名字;

后端端口我修改成了8888,不修改的话是8080

2)前端获得数据之后开始循环

provinceChange(that) {
            let provinceCode = that;
            for (let i = 0; i < this.provinceArr.length; i++) {
                let province = this.provinceArr[i];
                if (province.type == provinceCode) {
                    this.cityArr = province.cityArr;
                }
            }
        }, 
cityChange(that) {
            let cityCode = that;
            for (let i = 0; i < this.cityArr.length; i++) {
                let city = this.cityArr[i];
                if (city.type == cityCode) {
                    this.countryArr = city.countryArr;
                }
            }
        }

 方法中的参数that就是用户点击了下拉框以后返回的值,直接取来用就行

三.实现三级联动

1)效果图

 2)选择省

3)根据省选择市

4)根据市选择区县

以上就是本人从后端开发三级联动到前端实现的全过程,代码有优化的空间,希望大家一起交流,欢迎各位指导.