开发笔记:uniapp+vue+微信小程序 picker +后端 省市区三级联动

news2024/9/22 11:28:49

写在前面

未采用: 前端放置js 或者 json文件进行 省市区三级联动
采用: 前端组件 + 后端接口实现三级联动
原因:首先微信小程序有大小限制,能省则省,其次:方便后台维护省市区数据,完整省市区每年更新好像还是挺频繁的

方案

后端保存数据格式

例如
在这里插入图片描述

前端要展示 “福建省-厦门市-集美区“ 直接根据 - 分割截取就行

12,1,3 :代表选择数据 对应项中的第几个
9261586716360729,9261586716360744:代表选择省跟市的id

在这里插入图片描述
这两个数组串 主要是回显数据用 ,如下,点击展开回显
在这里插入图片描述

前端实现代码 [有注释说明]

template
	<uni-popup ref="cityDialog" type="bottom">
			<view class="uni-list">
				<view class="uni-list-cell">
					<view class="uni-list-cell-left">
						当前选择
					</view>
					<view class="uni-list-cell-db">
						<picker @columnchange="columnchange" @change="changeAddress" range-key="name" :value="value"
							:range="addressList" mode="multiSelector">
								<view class="uni-input">{{cityValue}}</view>
						</picker>
					</view>
				</view>
			</view>
		</uni-popup>
data
export default {
   data() { 
     return { 
       //存放三级联动数据
       addressList: [[],[],[]],
       //选择的省回显id
       province: "",
       //选择的市回显id
	   city: "",
	   //回显值
	   value: [],
	   //前端展示数据
	   cityValue:'',
	   timer:null
     }
   }
}
create
	created() {
			console.log("created...")
			this.userInfo = uni.getStorageSync("userInfo");
			const info = this.userInfo.city
			if (info) {
			//info 就是上面方案里说的数据库city字段值  
			// 福建省-厦门市-集美区-12,1,3-9261586716360729,9261586716360744
			//前端展示数据
			this.cityValue = info.split('-').slice(0, 3).join('-');
			//数据库 省市表主键 id
			const idPart = info.split('-')[4].split(',');
			this.province = idPart[0]
			this.city = idPart[1]			
			this.value = []
			// 添加回显id 
			this.value.push(...info.split('-')[3].split(',').map(Number));	
            }
			//初始化省数据
			this.initProvince(); 		
		},
methods
columnchange(e) {
				clearTimeout(this.timer)
				const _this = this
				this.timer = setTimeout(() => {
					const {
						column,
						value
					} = e.detail
					const item = {
						..._this.addressList[column][value]
					}
					if (column === 0) {
						this.province = item.id
						//清楚选择二级数据,不然切换别的省,第三级永远是上一次选择
						this.city = ''
						_this.loadCity(item.id)
					} else if (column === 1) {
						this.city = item.id
						_this.loadThird(item.id)
					}
				}, 500)
			},
		initProvince() {
		      //调用接口获取省数据
				listProvince().then(res => {
					if (res.code == 200) {
						this.addressList.splice(0, 1, [...res.data])
						//如果this.province 数据没有,表示数据库没有记录
						if (!this.province) {
							this.province = res.data[0].id
						}
						this.loadCity(this.province)
					}

				})
			},
			loadCity(parentId) {
				listCity(parentId).then(res => {
					if (res.code == 200) {
						this.addressList.splice(1, 1, [...res.data])
						if(!this.city) {
							this.city = res.data[0].id
						}
						this.loadThird(this.city)
					}

				})
			},

			loadThird(parentId) {
				listCity(parentId).then(res => {
					if (res.code == 200) {
						this.addressList.splice(2, 1, [...res.data])
					}

				})
			},
	changeAddress(e) {
				console.log("e", e)
				const _this = this
				_this.value = []
				_this.value.push(...e.detail.value)
				const arr = e.detail.value
				let str = ''
				arr.forEach((el, index) => {
					const {
						name
					} = _this.addressList[index][el]

					str += `${index ? '-':''}${name}`
				})
				this.cityValue = str
				// 最终数据 省-市-区-选择数据第几个(逗号隔开)- 选择数据id(逗号隔开) 
				//例:福建省-厦门市-集美区-12,1,3-9261586716360729,9261586716360744
				str = str + "-" + e.detail.value + "-" + this.province + "," + this.city
				//TODO 保存,或者修改 数据 
				this.editInfo.city = str
			},

后端实现代码

后端就两个接口 简单接口
 /**
     *  获取省份
     * @return  province
     */
   @GetMapping("listProvince")
    public AjaxResult  listProvince () {
        return AjaxResult.success(sysProvinceCityDistrictService.listProvince());
    }


```bash
 /**
     *  获取市/区县
     * @return  province
     */
    @GetMapping("listCity")
    public AjaxResult  listCity (@RequestParam("parentId") String parentId) {
        return AjaxResult.success(sysProvinceCityDistrictService.listCity(parentId));
    }

service接口文件这边就忽略了,直接impl逻辑

逻辑也很简单,查缓存 ,没有就数据库,有就缓存

Constants.NUMBER_ZERO 常量 0

@Override
public List<CityVo> listProvince() {
        if (Boolean.TRUE.equals(redisTemplate.hasKey(CacheConstants.CITY_CACHE_KEY))) {
            //从缓存获取
            return (List<CityVo>) redisTemplate.opsForValue().get(CacheConstants.CITY_CACHE_KEY);
        }
        List<CityVo> cityVos = sysProvinceCityDistrictMapper.listProvince();
        if (CollectionUtils.isEmpty(cityVos)) {
            return null;
        }
        redisTemplate.opsForValue().set(CacheConstants.CITY_CACHE_KEY, cityVos);
        return cityVos;
    }

    @Override
    public List<CityVo> listCity(String parentId) {
        List<CityVo> list = new ArrayList<>();
        List<SysProvinceCityDistrict> reultList;
        if (Boolean.TRUE.equals(redisTemplate.hasKey(CacheConstants.CITY_CACHE_KEY_CITY))) {
            //从缓存获取
            reultList = (List<SysProvinceCityDistrict>) redisTemplate.opsForValue().get(CacheConstants.CITY_CACHE_KEY_CITY);
        } else {
            QueryWrapper<SysProvinceCityDistrict> query = new QueryWrapper<>();
            query.ne("parent_id", Constants.NUMBER_ZERO);
            reultList = sysProvinceCityDistrictMapper.selectList(query);
        }
        if (CollectionUtils.isEmpty(reultList)) {
            return list;
        }
        reultList.stream().filter(s -> s.getParentId().equals(parentId))
                .forEach(info -> {
                    CityVo cityVo = new CityVo();
                    cityVo.setId(info.getId());
                    cityVo.setName(info.getName());
                    list.add(cityVo);
                });
        redisTemplate.opsForValue().set(CacheConstants.CITY_CACHE_KEY_CITY, reultList);
        return list;
    }

CityVo

/**
 * @author rongpeng.xia
 * @date 2024-08-13 10:33:59
 */
@Data
public class CityVo  implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;

    private String name;
}

(SysProvinceCityDistrict)表实体类

/**
 * (SysProvinceCityDistrict)表实体类
 *
 * @author xiarp
 * @since 2024-08-12 15:58:13
 */
@SuppressWarnings("serial")
@Data
public class SysProvinceCityDistrict implements Serializable {

    private static final long serialVersionUID = 286422671100375146L;

    /**
     * id
     */
    private String id;
    /**
     * 名字
     */
    private String name;

    /**
     * 父id
     */
    private String parentId;
    /**
     * 编码
     */
    private String code;
    /**
     * 父编码
     */
    private String parentCode;
    /**
     * 创建者
     */
    private Long createId;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 修改者
     */
    private Long updateId;
    /**
     * 修改时间
     */
    private Date updateTime;
}

前端参考的连接:https://blog.csdn.net/m0_73205643/article/details/140954162

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2037101.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HR招聘测评,什么样的候选人无法通过面试

当下企业招聘普遍采用在线人才测评的方式&#xff0c;比传统的面试更加深入&#xff0c;也更加全面的掌握候选人的各方面信息&#xff0c;尤其是综合素质方面&#xff0c;是传统面试所无法比拟的。 在线人才测评的环节&#xff0c;往往安排在面试前&#xff0c;或者是在面试后…

Canvas:二次贝塞曲线

目录 1. 含义2. 方法说明3. 绘制对号4. 绘制聊天框 1. 含义 二次贝塞尔曲线是从起始点开始&#xff0c;通过控制点影响&#xff0c;最终到达终点的平滑曲线。 控制点虽然不在曲线上&#xff0c;但它决定了曲线的形状。 通过调整控制点的位置&#xff0c;可以改变曲线的弯曲方向…

苍穹外卖项目DAY02

苍穹外卖项目Day02 1、员工管理 1.1、新增员工 1.1.1、需求分析和设计 产品原型&#xff1a; 接口设计&#xff1a; 数据库设计&#xff08;employee表&#xff09;&#xff1a; 1.1.2、代码开发 根据新增员工接口设计对应的DTO&#xff1a; 注意&#xff1a;当前端提交的…

(javaweb)分层解耦

目录 一.三层架构 二.分层解耦 三.IOC&DI入门 四.IOC详解 五. DI详解 一.三层架构 复用性差&#xff0c;难以维护和管理 前端发起请求&#xff0c;先会到达controller&#xff0c;再调用service进行逻辑处理&#xff0c;逻辑处理的前提是先拿到数据&#xff0c;到dao…

模拟电子技术(上海交大 郑益慧)

概述 深入学习基础器件、然后基于基础器件做应用电路设计, 然后做放大电路设计,在这做多级放大电路 最后 构成了集成放大器 改善电路性能、让电路稳定,最终要的思想,就是引入反馈 如何学习 多练习、多实践增加感性(sumulink) 仿真 本征半导体与杂质半导体 二极管 单向导…

Java Facade 模式(外观模式)增强您的架构

通过我们的深入解释和实际示例揭示 Java Facade 模式的简单性 - 简化您的代码并增强您的架构。 您是否厌倦了让您头疼的乱七八糟的代码&#xff1f;您是否在为难以操作和维护的复杂软件而苦恼&#xff1f;那么让我们来谈谈外观 — — 不&#xff0c;不是建筑物的正面&#xff0…

Ceph分布式存储系统的搭建与使用

目录 一. 环境准备 二. 安装Docker 三. admin节点安装cephadm 四. admin节点给另外四个主机导入镜像 五. 向集群中添加节点 六. Ceph使用 列出可用设备 清除设备数据---针对有数据的设备 检查 OSD 状态 Ceph 集群中添加一个新的 OSD 查看集群的健康状态 指定MDS 列…

Javascript 基本引用类型

思维导图 Javascript基本引用类型思维导图 1:date的简单使用 let date new Date() // 获取当前的时间 年月日时分秒 获取时间 getTime() // 返回日期的毫秒表示&#xff1b;与 valueOf()相同 getFullYear() // 返回 4 位数年&#xff08;即 2019 而不是 19&#xff09; ge…

SD-WAN企业组网:与传统组网有何不同?

很多企业已经尝试过使用SD-WAN来进行组网。SD-WAN代表着一种新兴的网络连接技术&#xff0c;与传统的网络架构相比&#xff0c;它在许多方面都有明显的不同。 SD-WAN基于软件定义网络&#xff08;SDN&#xff09;的概念&#xff0c;提供集中化的网络控制和智能优化&#xff0c;…

软考:软件设计师 — 13.数据结构

十三. 数据结构 数据结构部分也可参考文章&#xff1a;Java数据结构知识点 — 5种常见数据结构 1. 线性结构 &#xff08;1&#xff09;线性表 顺序表 线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的数据元素&#xff0c;从而使得逻辑上相邻的两个元素…

仿RabbiteMq简易消息队列基础篇(future操作实现异步线程池)

TOC 介绍 std::future 是C11标准库中的一个模板类&#xff0c;他表示一个异步操作的结果&#xff0c;当我们在多线程编程中使用异步任务时&#xff0c;std::future可以帮助我们在需要的时候&#xff0c;获取任务的执行结果&#xff0c;std::future 的一个重要特性是能…

lvm知识终结

、什么是 LVM LVM 是 Linux 下对磁盘分区进行管理的一种工具&#xff0c;适合管理大存储设备&#xff0c;并允许用户动态调整文件系统的大小 lvm 常用的命令 功能 PV 管理命令 VG 管理命令 LV 管理命令 scan 扫描 pvscan vgscan lvscan create 创建 pvcreate v…

水仙花语:花中情诗,心灵低语

一、水仙花语的丰富内涵 水仙花的花语丰富多样&#xff0c;其中“纯洁”是其最为显著的象征之一。水仙花洁白无瑕的花瓣&#xff0c;宛如纯洁无暇的心灵&#xff0c;给人以清新、高雅之感。这种纯洁不仅体现在花朵的外观上&#xff0c;更蕴含着一种纯净、美好的精神内涵&#x…

【JS逆向学习】AES加密文本如何在python中进行调用js解密

对于上边的图片我们用F12找到我们就发现一个无限循环debugger , 我的解决方案是关闭调试 在一个currentitems中发现全是加密的数据 我通过ctrl + shift +f 搜索AES P 这就是解密的js函数,存到js中,进行处理 const crypto = require(crypto) var CryptoJS = require(crypt…

2.7单窗口中显示多幅图像

目录 1.实验原理 2.实验代码 3.运行结果 1.实验原理 在Opencv中&#xff0c;我们可以综合利用坐标变换与Rect区域提取来实现单窗口显示多幅图像。首先根据输入图像个数与尺寸确定输入源图像小窗口的构成形态&#xff0c;然后设定每个图像小窗口的具体构成&#xff0c;包括边…

超级外链工具,可发9600条优质外链

超级外链工具&#xff0c;是一款在线全自动化发外链的推广工具。使用本工具可免费为网站在线批量增加外链&#xff0c;大大提高外链发布工作效率&#xff0c;是广大草根站长们必备的站长工具。 外链工具只是网站推广的辅助工具&#xff0c;一般适用于短时间内无法建设大量外链…

stm32入门学习16-闪存

&#xff08;一&#xff09;闪存 在之前的学习中&#xff0c;已经学习过了W25Q64这个外挂闪存&#xff0c;在stm32内部也有一块闪存&#xff0c;其主要用于存放我们编译的代码&#xff0c;如果我们需要一些掉电不丢失的数据&#xff0c;但是又懒得外挂一块闪存&#xff0c;就可…

树莓派4b换源+安装neo4j知识图谱

烧录树莓派系统&#xff0c; ssh 1.在SD中的boot区中&#xff0c;新建两个文件ssh(没有任何后缀)和wpa_supplicant.conf。 2.往wpa_supplicant.conf中写入 countryCN ctrl_interfaceDIR/var/run/wpa_supplicant GROUPnetdev update_config1 network{ ssid“wifi账号” psk“…

VS Code 配置docker 管理员权限终端

问题描述 在容器中需要使用sudo或者su root时候&#xff0c;权限不够&#xff0c;被灵魂提问。 然而&#xff0c;镜像是官方发布的&#xff0c;翻遍了githubissues也没有找到password. 解决 Attach shell 在docker插件中&#xff0c;attach shell 可以直接获得shell。 所…