撸个微信小程序的省市区选择器

起因

微信小程序虽然已经有现成的封装好的省市区选择器给开发者使用,然鹅不幸的是,微信地址库的数据和公司用的地址库数据很难一一对上,那就只能撸起袖子自己写个组件了。

最终效果

最终效果

思维导图

思维导图

主要代码

组件 region-picker.js

/* region-picker.js */
import area from '本地 json 数据';
Component({properties: {showRegion: {type: Boolean,observer: function(newVal, oldVal) {this.setData({dialog: newVal,});},},regionValue: {type: Array,value: [],observer: function(newVal, oldVal) {if (newVal.length > 0) {let select = -1;for (let i = newVal.length - 1; i >= 0; i--) {if (newVal[i].id !== '') {select = i;break;}}// 除最低级别区(select = 2)以外,需要获取当前级别下一级的数据this.setData({['region.tabs']: newVal,['region.select']: select < 2 ? select 1 : select,}, () => {this.setData({area: this.getChildArea(select < 2 ? select 1 : select),});});}},},},data: {dialog: false,area: area,region: {tabs: [{name: '请选择',id: '',},{name: '请选择',id: '',},{name: '请选择',id: '',},],select: 0,},},methods: {// 关闭 picker 触发的方法emitHideRegion: function() {if (this.data.region.tabs[2].id === '') {wx.showToast({title: '请选择所在地',icon: 'none',duration: 2000,});return false;}let myEventDetail = {}; // detail对象,提供给事件监听函数let myEventOption = {}; // 触发事件的选项this.setData({dialog: !this.data.dialog,});myEventDetail = {showRegion: this.data.dialog,regionValue: this.data.region.tabs,};this.triggerEvent('myevent', myEventDetail, myEventOption);},bindRegionChange: function(e) {// 获取当前选中项的name和id并赋值给data中的数据let id ='region.tabs['   this.data.region.select   '].id';let name ='region.tabs['   this.data.region.select   '].name';this.setData({[id]: e.target.dataset.id,[name]: e.target.dataset.name,});// 除了三级以外的需要获取对应子选项if (this.data.region.select < 2) {this.setData({['region.select']:   this.data.region.select,}, () => {// 获取子选项this.setData({area: this.getChildArea(this.data.region.select),});});} else {// 三级选项选择完毕关闭省市区选择器this.emitHideRegion();}},getChildArea: function(level) {let _id = '';// 默认取完整的数据let _area = area;// 根据层级取当前层级下的数据for (let i = 0; i < level; i  ) {_id = this.data.region.tabs[i].id;for (let j = 0; j < _area.length; j  ) {if (_area[j].id === _id) {_area = _area[j]._child;break;}}}return _area;},// 省市区tab切换changeRegionLevel: function(e) {let level = e.target.dataset.level;// 三级选项的tab点击无效果if (level === 2) return false;// 当前选中tab和级别小于当前选中tab的状态都置为初始化状态for (let i = level; i < 3; i  ) {let string = 'region.tabs['  i  ']';this.setData({[string]: {name: '请选择',id: '',},});}this.setData({['region.select']: level,});this.setData({area: this.getChildArea(level),});},},
});

组件 region-picker.wxml

/* region-picker.wxml */
<view class="free-dialog {{dialog ? 'free-dialog--show' : ''}}"><view class="free-dialog__mask" bindtap="emitHideRegion"></view><view class="free-dialog__container"><view class="free-dialog__container__header"><view>选择所在地区</view><imagesrc="自行替换36rpx*36rpx的x图标"class="close"bindtap="emitHideRegion"></image></view><view class="free-dialog__container__content"><view class="free-content {{isIphoneX ? 'ipx' : ''}}"><view class="free-content__tabs"><viewclass="free-content__tabs__tab {{region.select === index ? 'select' : ''}}"wx:for="{{region.tabs}}"wx:key="{{index}}"wx:if="{{index <= region.select}}"data-level="{{index}}"bindtap="changeRegionLevel">{{item.name}}</view></view><scroll-view scroll-y class="free-content__scroll"><viewclass="free-content__scroll__item"wx:for="{{area}}"wx:key="id"data-id="{{item.id}}"data-name="{{item.name}}"bindtap="bindRegionChange">{{item.name}}</view></scroll-view></view></view></view>
</view>

组件 region-picker.wxss

/* region-picker.wxss */
.free-dialog__mask {position: fixed;top: 0;left: 0;right: 0;bottom: 0;z-index: 10;background: rgba(0, 0, 0, 0.7);display: none;
}
.free-dialog__container {position: fixed;left: 0;bottom: 0;width: 100%;background: #F1F1F1;transform: translateY(150%);transition: all 0.4s ease;z-index: 11;
}
.free-dialog--show .free-dialog__container {transform: translateY(0);
}
.free-dialog--show .free-dialog__mask {display: block;
}
.free-dialog__container__header {padding: 24rpx 30rpx;text-align: center;background: white;
}
.free-dialog__container__header .close {position:absolute;right:30rpx;top:31rpx;width:36rpx;height:36rpx;
}
.free-content {background: white;border-bottom: 40rpx solid white;
}
.free-content.ipx {border-bottom: 72rpx solid white;
}
.free-content__tabs__tab {display: inline-block;padding: 12rpx 46rpx;font-size: 32rpx;color: #333;border-bottom: 4rpx solid white;
}
.free-content__tabs__tab.select {border-color: #FA263C;
}
.free-content__scroll {padding: 0 40rpx;height: 480rpx;box-sizing: border-box;
}
.free-content__scroll__item {margin-top: 40rpx;height: 40rpx;line-height: 40rpx;font-size: 28rpx;color: #333;
}

页面的 WXML

/* 页面的 WXML */
<view bindtap="chooseRegion">请选择</view>
<view><text wx:if="{{regionValue[0].id}}">{{regionValue[0].name}}</text><text wx:if="{{regionValue[1].id}}">{{regionValue[1].name}}</text><text wx:if="{{regionValue[2].id}}">{{regionValue[2].name}}</text>
</view>
...
<region-pickerregion-value="{{regionValue}}"show-region="{{showRegion}}"bind:myevent="emitHideRegion">
</region-picker>

页面的 js

/* 页面的 js */
Page({data: {regionValue: [],showRegion: false,},chooseRegion: function() {this.setData({showRegion: true,});},emitHideRegion: function(e) {this.setData({showRegion: e.detail.showRegion,regionValue: e.detail.regionValue,});},
});

总结

需要注意下的是,最低级别区级别是个特殊的临界点,因为区后面没有更低级别,所以不需要获取下一级别的数据,也不能触发 tab 事件。

然后父组件传递子自组件的值,如果后期父组件变更了这个值,子组件可以在响应函数 observer 里监听到值的变化。

我本次使用的本地省市区 JSON 数据格式为:

/* area.js */
module.exports = [{id: '...',name: '...',_child: [{id: '...',name: '...',_child: [{id: '...',name: '...'}, ...]}, ...]
}, ...]

写的不是特别好,也希望能帮助到有需要的人吧,有疑问戳微信小程序官方文档,没有什么比官方文档更靠谱的了!

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

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

相关文章

docker build 变量_DockerFile 设置环境变量

镜像的Layer 在docker docs里面有一句话: We’ve already seen that Docker images are read-only templates from which Docker containers are launched. Each image consists of a series of layers. Docker makes use of union file systems to combine these layers into…

计算机巧用剪纸做画册教案,大班绘画剪纸制作的教案总结

大班绘画剪纸制作的教案总结第一篇&#xff1a;写生画&#xff1a;目标&#xff1a;培养幼儿细微的观察能力&#xff0c;进一步引导幼儿能抓住人物的典型特征&#xff0c;大胆表现。准备&#xff1a;不同脸型人物的范画两张。过程&#xff1a;一、导入。1&#xff0e; 组织游戏…

python之路_day6

本节内容&#xff1a;面向对象编程介绍为什么要用面向对象进行开发&#xff1f;面向对象的特性&#xff1a;封装、继承、多态类、方法、引子 你现在是一家游戏公司的开发人员&#xff0c;现在需要你开发一款叫做<人狗大战>的游戏&#xff0c;你就思考呀&#xff0c;人狗作…

Netty 简介

上文我们介绍了NIO和BIO的区别&#xff0c;NIO相对于BIO是一次很大的进步。但我们平时开发中并不会使用NIO。这是因为NIO在开发中存在以下问题 NIO的类库和API繁杂&#xff0c;使用麻烦&#xff0c;需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等&am…

简单性与鲁棒性–在锁定文件处理中展示

今天&#xff0c;我们将讨论在设计不足和过度设计之间保持简单&#xff0c;愚蠢&#xff08;KISS&#xff09;和鲁棒性的设计价值之间的冲突。 我们正在编写一个批处理Java应用程序&#xff0c;需要确保在服务器上一次最多运行一个实例。 一个团队成员有一个很好的想法&#x…

mssql导出数据到mysql_MSSQL数据导出到MYSQL

MSSQL数据导出到MYSQL花了一天时间把MSSQL里的数据导出到MYSQL&#xff0c; 好麻烦&#xff0c;二个数据库都是阿里云买的云服务器。先上阿里云控制面板&#xff0c;备份下MSSQL数据库&#xff0c;下载备份下来&#xff0c;在本地电脑上还原2.本地MSSQL数据库上执行select * in…

演示教学法在计算机基础课程中的应用,演示教学法在《计算机基础》课程中的应用...

科 学 论坛演示教学法在《计算机基础》课程中的应用撩淹阳辉(湖南铁路科技职业技术学院 湖南 株洲 412006)摘 要&#xff1a;文章通过谈了笔者自己对《计算机基础》课程中演示教学方法的思考&#xff0c;明确了在《计算机基础》课程中运用演示教学的实效&#xff0c;但同时针对…

MUI调用原生自定义方法实现计算缓存与清空缓存

由于项目需要最近在做webapp开发用的是MUI框架&#xff0c;自己本来是做原生开发的&#xff0c;在开发的时候有一个需求是实现计算缓存和清除缓存的功能&#xff0c;原生java方法实现轻轻松松&#xff0c;网上代码一大把&#xff0c;不过是webapp倒是不好搞&#xff0c;MUI自己…

mysql dump 表数据 shell 脚本

userubuntu:~$ cat mysql_jd_espc_dump.sh ## 这段语句为导出语句mysqldump -uroot -ppassword espc --ignore-tableespc.contract --ignore-tableespc.signature --ignore-tableespc.invitation > ~/dump_1.sql## 下面是其他定制业务&#xff0c;不需要关注 sed s/MyISAM/…

Java中的多重继承与组合vs继承

有时我写了几篇有关Java 继承 &#xff0c; 接口和组成的文章。 在这篇文章中&#xff0c;我们将研究多重继承&#xff0c;然后学习组成优于继承的好处。 Java中的多重继承 多重继承是创建具有多个超类的单个类的能力。 与其他一些流行的面向对象的编程语言&#xff08;例如C …

mysql改date格式_mysql数据库修改添加Date格式列的方法

import java.sql.*;import java.text.DateFormat;//数据库的查询public class SelectTable {String dbDriver"com.mysql.jdbc.Driver";String dbUrl"jdbc:mysql://localhost:3306/sss";//根据实际情况变化String username"root";String password…

开源|蚂蚁金服开源AntV F2:一个专注于移动,开箱即用的可视

小蚂蚁说&#xff1a;AntV 是蚂蚁金服全新一代数据可视化解决方案&#xff0c;主要子产品包括 G2、G6、F2。此前我们已经相继发布过AntV的相关开源消息与版本迭代&#xff0c;包括《蚂蚁金服开源&#xff1a;数据驱动的高交互可视化图形语法G2》&#xff0c;《开源 | 蚂蚁金服开…

数学第一单元计算机思维导图,七年级下册数学第一单元思维导图图片

七年级下册数学第一单元思维导图图片_七年级数学下册思维导图第五章 相交线与平行线思维导图???邻补角? ???两条直线相交??对顶角???????相交线????????两条直线被第??三垂条直直线所截(三线八角)?????内同 同错旁 位角内 角角相 交 线 与 平 行…

DMA(Direct Memory Access)简介

什么是DMA&#xff08;Direct Memory Access&#xff09; DMA绕过CPU&#xff0c;在内存和外设之间开辟了一条 “隧道” &#xff0c;直接控制内存与外设之间的操作&#xff0c;并完全由硬件控制。这样数据传送不经过cpu&#xff0c;不需要保护、恢复CPU现场等一系列操作&#…

Puppeteer入门初探

本文来自网易云社区作者&#xff1a;唐钊最近在看 node 爬虫相关的一些东西&#xff0c;我记得还是很久以前常用的 node 爬虫工具还是 superagengtcherrio,他们的思路是通过发起 http 请求然后截取 respone 的内容&#xff0c;但是随着前端mvvm等框架的盛行&#xff0c;现在更多…

访问量大如何增加服务器,服务器流量过大原因及解决方法

造成网站服务器流量过大的原因&#xff1a;1.网站规模较大(比如门户网站、网络商城等)&#xff0c;即网站本身访问量需求大&#xff0c;查看网站的Page View值、Hits值、日流量都很高。2.网站页面设计不合理&#xff0c;页面中包含大图片或音频、视频文件等文件&#xff0c;导致…

关于VUE项目地图开发中大量点标记绘制一些总结

问题说明 在地图开发中&#xff0c;当地图中绘制大量的标记点后&#xff0c;无论是拖动或者缩放&#xff0c;都会感觉到明显的卡顿现象。&#xff08;一般超过800个点后就比较明显了&#xff09;.在平时的工作业务中&#xff0c;由于公司的实时监控页面需要展现5000-20000车辆…

如何使用Java 5 Executor框架创建线程池

Java 5以Executor框架的形式在Java中引入了线程池&#xff0c;它允许Java程序员将任务提交与任务执行分离。 如果要使用Java进行服务器端编程&#xff0c;则线程池是维护系统可伸缩性&#xff0c;鲁棒性和稳定性的重要概念。 对于那些不熟悉Java中的线程池或这里的线程池的概念…

fedora python3-mysql_fedora 安装python mysql

如果你服务器环境允许yum&#xff0c;安装MySQL-python模块就很简单了。如果直接安装不行&#xff0c;先安装MySQL-devel后正常运行yum install mysql-develyum install MySQL-python -y1yum install MySQL–python–y当然也可以源码安装该模块首先安装 setuptools&#xff0c;…

var let 区别

var a 5; var b 10;if (a 5) {let a 4; // if 块级作用域var b 1; // 函数级作用域console.log(a); // 4console.log(b); // 1 } console.log(a); // 5 console.log(b); // 1var声明的变量是函数级的或者是全局的&#xff0c;而let用于声明块级作用域。 在函数或程序顶层…