vue利用级联选择器实现全国省市区乡村五级菜单联动

vue利用级联选择器实现全国省市区乡村五级菜单联动_第1张图片

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。

现在是:2022年2月13日20:09:27

今天分享一个五级级联地址的组件的使用吧。

前言

接到这样的一个需求:需要根据地址查询列表信息,地址可以分别按照省、市、县、乡、村 五级作为条件查询。

如果但是这个需求还好说,以前使用的方式是放五个下拉列表,通过懒加载的方式,根据省得到该省下的市,根据市得到该市下的县……最后可以得到村的级别,然后作为条件查询,也就是下面的这种方式:

vue利用级联选择器实现全国省市区乡村五级菜单联动_第2张图片 image-20220213201630629 a10cb542ab3ce76e329c578ee43c51b5.png image-20220213201641535

但是,客户说,太长了……因为他的另一个需求是这样的:

vue利用级联选择器实现全国省市区乡村五级菜单联动_第3张图片 image-20220213203322417

如果放5个的话,就会造成装不下的bug。

vue利用级联选择器实现全国省市区乡村五级菜单联动_第4张图片 image-20220213203822894

实现思路

原来采用的是select,现在看来,select显然不是最好的解决方式,去element-ui上面看了看,发现了另一个组件:Cascader 级联选择器,样式如下:

vue利用级联选择器实现全国省市区乡村五级菜单联动_第5张图片 image-20220213204120997

于是就把这个Cascader 组件改了改,改成了省市区乡村的组件,同时也做成了公共组件,项目中可以多次共用。

数据表结构

全国省市区乡村没有使用json的方式,将所有的省市区乡村信息都放在了数据库中,用的时候根据父级编号查询,数据库表结构如下:

vue利用级联选择器实现全国省市区乡村五级菜单联动_第6张图片 image-20220213204531326

级联实现地址联动

实现思路:页面初次加载的时候,将全国所有省查询出来,封装放在级联组件Cascader中,当用户选择某个省的时候,将当前省的编码作为父级编码,去查询所有的市。比如选的山东省,查询出来的就是山东所有市,济南,聊城,菏泽等。

为了解决系统性能问题,我将查询出来的信息都放在了redis缓存中了,缓存里面没有的话去数据库里面找去,有则在缓存中取,效率要高点儿。

下面是公共组件中的代码:






关键代码都有相应的注释,应该看起来都没有问题。

或许有些地方的代码冗余,但是我没法再优化了……这个组件大致的功能就是将用户选择的地址信息,传递到父组件中,父组件通过getCheckedAddressInfo函数拿到用户选择的地址信息,不管选择哪一级都可以,最后在根据地址信息做其他操作。

listArea方法:根据条件查询地址信息,传递的参数是地址实体,在本文的最后我附上后台的实现代码。

级联地址组件的使用

使用方法也很简单,只需这么几步:

1.先导入组件:

import addressCommonComponentsUtils from "../area/addressCommonComponentsUtils";

2.注册组件:

export default 里面写如下代码:

components: {
    "address-utils": addressCommonComponentsUtils,
    },
vue利用级联选择器实现全国省市区乡村五级菜单联动_第7张图片 image-20220213212322706

3.在template中引入级联地址组件:


    

4.在methods中写getCheckedAddressInfo方法回去选择的地址信息:

//获取用户选择的地址信息
    getCheckedAddressInfo(value){
        //给地址栏中赋值
        this.queryParams.fieldProvince = value.sonProvinceName;
        this.queryParams.fieldCity = value.sonCityName;
        this.queryParams.fieldArea = value.sonAreaName;
        this.queryParams.fieldStreet = value.sonStreetName;
        this.queryParams.fieldCommunity = value.sonCountryName;
    },

参数说明:

编码:比如北京是110000,山西是:140000等

  • //省 `sonProvinceValue,

  • //市 `sonCityValue,

  • //区 `sonAreaValue,

  • //街道 `sonStreetValue,

  • //乡村 `sonCountryValue,

名字:比如北京是**【北京】,山西是【山西省】**

  • //省 sonProvinceName,

  • //市 `sonCityName,

  • //区 `sonAreaName,

  • //街道 `sonStreetName,

  • //乡村 sonCountryName,

最后实现的效果如下:

vue利用级联选择器实现全国省市区乡村五级菜单联动_第8张图片 image-20220213213301547

附:后台查询地址的代码

area.js:

// 查询地址列表
export function listArea(query) {
  return request({
    url: '/system/area/list',
    method: 'get',
    params: query
  })
}

SysAreaController中的代码:

@Autowired
    private ISysAreaService sysAreaService;

    /**
     * 查询地址列表
     */
    //@PreAuthorize("@ss.hasPermi('system:area:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysArea sysArea)
    {
       // startPage();
        List list = sysAreaService.selectSysAreaList(sysArea);
        return getDataTable(list);
    }

SysAreaServiceImpl中的代码:

@Autowired
    private SysAreaMapper sysAreaMapper;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询地址
     * 
     * @param id 地址主键
     * @return 地址
     */
    @Override
    public SysArea selectSysAreaById(Long id)
    {
        return sysAreaMapper.selectSysAreaById(id);
    }

    /**
     * 查询地址列表
     * 
     * @param sysArea 地址
     * @return 地址
     */
    @Override
    public List selectSysAreaList(SysArea sysArea) {
        //分批次判断地址
        List areaList = new ArrayList<>();
        //地址对象
        SysArea area = new SysArea();
        if(sysArea.getPid()==null){
            sysArea.setPid("100000");
        }
        //市、区县、街道、村
        if (redisCache.getCacheList(sysArea.getPid() + "ListCache").size()==0) {
            System.out.println("=========================走数据库了=========================");
            area.setType(sysArea.getType());
            //将父级编号放进来
            area.setPid(sysArea.getPid());
            areaList = sysAreaMapper.selectSysAreaList(area);
            redisCache.setCacheList(sysArea.getPid() + "ListCache", areaList);
        } else {
            System.out.println("=========================走缓存了=========================");
            //从缓存中取出来
            areaList = redisCache.getCacheList(sysArea.getPid() + "ListCache");
        }
        return areaList;
    }

Mapper层和Service的接口层就不放了,就正常写,返回集合就行:

/**
     * 查询地址列表
     * 
     * @param sysArea 地址
     * @return 地址集合
     */
    public List selectSysAreaList(SysArea sysArea);

最后是mapper.xml中的sql:


        select id, name, area_id, pid, type, status, del_flag, create_time, update_time, pids, m_pid, m_pids, m_type, region, remark from sys_area
    

    
        
        
             and name like concat('%', #{name}, '%')
             and area_id = #{areaId}
             and pid = #{pid}
             and type = #{type}
             and status = #{status}
             and pids = #{pids}
             and m_pid = #{mPid}
             and m_pids = #{mPids}
             and m_type = #{mType}
             and region = #{region}
        
    

总结

好了,今天分享的就这些了,源码也都贴上来啦,记录记录,一来或许可以帮助大家,二来自己以后用的时候,也可以直接上来扒代码了。

下一篇:springboot解析word文档,包括复杂的图片,复选框等。

问:你知道CV工程师是啥吗?

你可能感兴趣的:(数据库,java,python,vue,mysql)