ElementUi+Springboot+mybatisplus实现级联选择省市县

备注:这种方法构造不是很好,有大佬可以指点下使用组合模式构造树形机构。

1.数据准备

创建一个表,id是编码,name名称,pid父级的id

CREATE TABLE `chinaMap` (
  `Id` int NOT NULL,
  `Name` varchar(40) DEFAULT NULL,
  `Pid` int DEFAULT NULL,
  PRIMARY KEY (`Id`),
  KEY `FK_chinaMap_REFERENCE_chinaMap` (`Pid`),
  CONSTRAINT `FK_chinaMap_REFERENCE_chinaMap` FOREIGN KEY (`Pid`) REFERENCES `chinaMap` (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

文件的话,可以下载下,插入语句就在多说了。

2.后台java实现

后台使用Springboot+mybatisplus

实体类

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("`chinaMap`")
public class ChinaMap implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 行政区划
     */
    @TableId(value = "Id", type = IdType.AUTO)
    private Integer Id;
    /**
     * 名字
     */
    @TableField(value = "Name")
    private String Name;
    /**
     * 父级Id
     */
    @TableField(value = "PId")
    private Integer PId;
}

mapper类

@Mapper
public interface MapMapper extends BaseMapper<ChinaMap> {
    @Select("SELECT Id, Name, Pid FROM test.chinaMap where Pid=#{pid}")
    List<ChinaMap> getMapListByPid(Integer pid);
}

controller 类

@RestController
@RequestMapping("/springboot/map")
@Slf4j
public class MapController {

    @Resource
    IMapService mapService;

    @GetMapping("/getMapList/{Pid}")
    public List<ChinaMap> getMapList(@PathVariable("Pid")Integer Pid){
        return mapService.getMapListByPid(Pid);
    }

    /**
     * 获取tree
     * @return
     */
    @GetMapping("/getMapTreeList")
    public List<MapTree> getMapTreeList(){
        return mapService.getMapTreeList();
    }

}

service接口

@Service
public interface IMapService extends IService<ChinaMap> {
    List<ChinaMap> getMapListByPid(Integer pid);
    List<MapTree> getMapTreeList();
}

1.第一种方式使用,选择省份触发获取城市实现

@Service
public class IMapServiceImpl extends ServiceImpl<MapMapper, ChinaMap> implements IMapService {
    @Autowired
    MapMapper mapMapper;

    /**
     * 根据ID获取树
     * @param pid
     * @return
     */
    @Override
    public List<ChinaMap> getMapListByPid(Integer pid) {
        return mapMapper.getMapListByPid(pid);
    }
}

2.直接构造树形结构

vo类

@Data
@Accessors(chain = true)
public class MapTree {
   private Integer Id;
   private String Name;
   private Integer PId;
   //树形结构
   private List<MapTree> children;
}

手动构造树形结构

List<MapTree> mapTrees = new ArrayList<>();
       //顶级
       MapTree mapTree = new MapTree();
       mapTree.setId(0);
       mapTree.setName("中国");
       //查询所有的省份
       List<ChinaMap> provinceMaps = mapMapper.getMapListByPid(0);
       List<MapTree> provinces = new ArrayList<>();
       for(ChinaMap pro :provinceMaps){
           //遍历所有的省份下的市级城市
           MapTree province = new MapTree();
           province.setId(pro.getId());
           province.setName(pro.getName());
           province.setPId(0);
           List<ChinaMap> cityMaps = mapMapper.getMapListByPid(pro.getId());
           List<MapTree> citys =  new ArrayList<>();
           for (ChinaMap c:cityMaps){
               MapTree city = new MapTree();
               city.setId(c.getId());
               city.setName(c.getName());
               city.setPId(pro.getId());
               List<ChinaMap> cuntys = mapMapper.getMapListByPid(c.getId());
               List<MapTree> countys =  new ArrayList<>();
               for(ChinaMap cty: cuntys){
                   countys.add(new MapTree().setName(cty.getName()).setId(cty.getId()).setPId(c.getId()));
               }
               city.setChildren(countys);
               citys.add(city);
           }
           province.setChildren(citys);
           provinces.add(province);
       }
       mapTree.setChildren(provinces);
       mapTrees.add(mapTree);
       return mapTrees;
   }

3.前端页面

分别使用select选择器和级联选择器实现。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>级联选择</title>
</head>
<!--script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script-->
<!--引入静态的路径-->
<script type="text/javascript" src="js/vue.min.js"></script>
<!--script src="https://unpkg.com/element-ui/lib/index.js"></script-->
<script type="text/javascript" src="js/index.js"></script>
<!-- 引入样式 -->
<!--link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"-->
<link rel="stylesheet" href="css/index.css">
<!-- 引入组件库 -->
<!--引入通信框架-->
<!--script src="https://unpkg.com/axios/dist/axios.min.js"></script-->
<script type="text/javascript" src="js/axios.min.js"></script>
<body>
<div id="app">
    <h1 style="background-color: #409EFF;text-align: center;">级联选择</h1>
    <template>
        <!--块状选择-->
       <el-cascader-panel class="el-cascader-panel" :options="options" :props="{ value: 'id',label: 'name',children: 'children'}"></el-cascader-panel>

        <el-form ref="form"  label-width="80px" size="mini">
            <el-form-item label="选择地址">
                <el-select clearable v-model="form.province"  placeholder="请选择省份" @change="provinceChange($event)">
                    <el-option v-for="(item,index) in form.provinceList" :key="item.id"  :label="item.name" :value="item.id"></el-option>
                </el-select>
                <el-select clearable  v-model="form.city"  placeholder="请选择城市" @change="cityChange($event)">
                    <el-option v-for="(item,index) in form.cityList" :key="item.id" :label="item.name" :value="item.id"></el-option>
                </el-select>
                <el-select  clearable v-model="form.county"  value-key="" placeholder="请选择区县">
                    <el-option v-for="(item,index) in form.countyList" :key="item.id"  :label="item.name" :value="item.id"></el-option>
                </el-select>
            </el-form-item>
        </el-form>
    </template>
</div>
</body>
</html>
<script>
    new Vue({
        el: "#app",
        //数据
        data() {
            return {
                options:[],//树形结构选择
                form:{
                    province:"",//选择的省
                    city:"", //城市
                    county:"",//区县
                    provinceList:[],//省份的list
                    cityList:[],//城市列表
                    countyList:[] //区县列表
                }
            };
        },
        //创建之前
        created() {
        },
        //初始化加载数据
        mounted() {
            //初始化加载商品数据
            this.getProvinceList();
            //加载树形结构
            this.getMapTreeList();
        },
        methods: {
            provinceChange(event){
                console.log(event);
                axios.get("/springboot/map/getMapList/"+event).then((res => {
                    console.log(res);
                    //绑定表格数据
                    if (res.status === 200) {
                        this.form.cityList = res.data
                    }
                }));
            },
            cityChange(event){
                console.log(event);
                axios.get("/springboot/map/getMapList/"+event).then((res => {
                    //绑定表格数据
                    if (res.status === 200) {
                        this.form.countyList = res.data
                    }
                }));
            },
            //获取省份列表
            getProvinceList(){
                axios.get("/springboot/map/getMapList/0").then((res => {
                    console.log(res);
                    //绑定表格数据
                    if (res.status === 200) {
                        this.form.provinceList = res.data
                    }
                }));
            },
            //获取树形结构列表
            getMapTreeList(){
                axios.get("/springboot/map/getMapTreeList").then((res => {
                    console.log(res);
                    //绑定表格数据
                    if (res.status === 200) {
                        this.options = res.data
                    }
                }));
            }
        }

    });
</script>
<style scoped>

</style>

4.效果

页面效果图

5.总结

现在用的是存在数据库的数据,可以使用现成的api调用查询来实现。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘同学要加油呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值