微信小程序自定义数据实现级联省市区组件

前言

在微信小程序中,官方文档提供的省市区组件,可以让用户更加方便快捷地选择省市区,但是官方提供的组件有一个缺点,无法自定义数据,但如果项目中需要使用自己的数据,显然就得寻找其它的组件实现。


官方组件

  • 优点

    • 使用官方组件具有稳定性和兼容性,可以保证在不同的微信小程序版本中正常运行;
    • 官方组件的使用文档详细,易于上手,可以快速实现级联省市区组件;
    • 官方组件的样式和交互效果都比较简洁,符合微信小程序的设计风格。
  • 缺点

    • 官方组件的样式和交互效果比较单一,无法满足一些特殊需求;
    • 官方组件的自定义能力比较有限,无法进行个性化定制。

wxml 文件

<picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}"><view class="picker">当前选择:{{region[0]}},{{region[1]}},{{region[2]}}</view>
</picker>

js 文件

Page({data: {region: [],},bindRegionChange: function (e) {console.log('picker发送选择改变,携带值为', e.detail.value)this.setData({region: e.detail.value})}
})

实现效果

在这里插入图片描述


vant-weapp 实现

vant-weapp 中为我们提供了级联选择器,并且组件的样式和交互效果比较丰富,可以满足各种特殊需求,使用这个组件也可以实现,但是 vant-weapp 也有一个问题,当数据量比较大时,组件就会变得异常卡顿。

wxml 文件

<van-field value="{{ fieldValue }}" is-link readonly label="地区" placeholder="请选择所在地区" bind:tap="onClick" />
<van-popup show="{{ show }}" round position="bottom"><van-cascader field-names="{{ fieldNames }}" wx:if="{{ show }}" value="{{ cascaderValue }}" title="请选择所在地区"options="{{ options }}" bind:close="onClose" bind:finish="onFinish" />
</van-popup>

js 文件

Page({data: {show: false,fieldValue: '',cascaderValue: '',fieldNames: {text: 'label',value: 'value',children: 'children',},options: [],},onLoad() {this.setData({options: JSON.parse(wx.getStorageSync('addressInfo'))})},onClick() {this.setData({show: true,});},onClose() {this.setData({show: false,});},onFinish(e) {const {selectedOptions,value} = e.detail;const fieldValue = selectedOptions.map((item) => item.label || item.value).join('/');this.setData({fieldValue,cascaderValue: value,})console.log(fieldValue);this.onClose()},
});

实现效果

肉眼可见非常卡顿,每点击一次都要等好几秒才能反应过来。

在这里插入图片描述


自定义组件

既然上面两种实现方法都不符合我们的需求,那么自己自定义组件就可以完全按照自己的需求进行设计和开发。

封装 wxml 文件

<picker mode="multiSelector" model:value="{{pickerValue}}" range-key="label" range="{{range}}" bindchange="onChange"bindcolumnchange="columnChange"><view><!-- 如果已经选择了选项,则显示选项的label属性,否则显示placeholder属性。 --><text wx:if="{{label}}"> {{ label }} </text><text style="color: #999" wx:else> {{ placeholder }}</text></view>
</picker>

封装 js 文件

Component({properties: {// placeholder为选择器的默认提示文字placeholder: {type: String,value: '请选择',},// value为选择器的默认值,类型为数组value: {type: Array,value: [],// observer监听value的变化,如果有值则调用setLabel方法设置选择器的labelobserver(selectedValues) {if (selectedValues && selectedValues.length) {this.setLabel();}}}},data: {// label为选择器的显示值label: '',// range为选择器的可选项,类型为数组,包含三个数组,分别为省、市、区/县range: [],// pickerValue为选择器的选中值,类型为数组,包含三个数字,分别为省、市、区/县的下标pickerValue: [],// addressList为选择器的数据源,类型为数组,包含省、市、区/县的信息addressList: [],},// attached生命周期函数,在组件实例进入页面节点树时执行attached() {// 获取地址列表,如果value为空则初始化rangethis.getAddressList().then(() => {if (!this.data.value.length) {this.initRange();}});},methods: {// getAddressItem方法用于将地址信息转换为选择器可用的格式getAddressItem(data) {return {label: data.label,value: data.value};},// setAddressList方法用于将地址列表转换为选择器可用的格式setAddressList(list) {return list.map((v) => this.getAddressItem(v));},// getAddressByCode方法用于根据value值获取地址信息及其在数组中的下标getAddressByCode(list = [], value) {let index = list.findIndex(item => item.value === value);return [index, list[index] || {}];},// openChildren方法用于根据value值打开下一级选择器openChildren(list, keys) {let result = [];const handle = (arr, keys) => {let newarr = arr.map((v, index) => {if (keys && keys.length) {let [currentKey, ...nextKey] = keys;if (currentKey === index && Array.isArray(v.children)) {handle(v.children, nextKey);}}return this.getAddressItem(v);});result.push(newarr);}handle(list, keys);return result.reverse();},// onChange方法为选择器的change事件处理函数,用于设置label和触发change事件onChange(e) {let [r1, r2, r3] = this.data.range;const [v1, v2, v3] = e.detail.value;const selected = [r1[v1], r2[v2], r3[v3]];const values = selected.map(v => v.value);const label = selected.map(v => v.label).join('-');this.setData({label});this.triggerEvent("change", {value: values,label});},// columnChange方法为选择器的columnchange事件处理函数,用于设置range和pickerValuecolumnChange(e) {const {column,value} = e.detail;this.setColumn(column, value);},// setColumn方法用于设置range和pickerValuesetColumn(column, value) {let addressList = this.data.addressList;if (!addressList || addressList.length === 0) return;let [r1, r2, r3] = this.data.range;if (column === 0) {r2 = this.setAddressList(addressList[value].children);r3 = this.setAddressList(addressList[value].children[0].children);this.setData({pickerValue: [value, 0, 0]});} else if (column === 1) {const [v1] = this.data.pickerValue;r3 = this.setAddressList(addressList[v1].children[value].children);this.setData({pickerValue: [v1, value, 0]});}this.setData({range: [r1, r2, r3]});},// setLabel方法用于设置labelsetLabel() {let addressList = this.data.addressList;if (addressList && addressList.length) {const [v1, v2, v3] = this.data.value;const [s1, {label: t1,children: l1}] = this.getAddressByCode(addressList, v1);const [s2, {label: t2,children: l2}] = this.getAddressByCode(l1, v2);const [s3, {label: t3}] = this.getAddressByCode(l2, v3);const label = [t1, t2, t3].filter(v => v).join('-');const pickerValue = [s1, s2, s3];const range = this.openChildren(addressList, [s1, s2, s3]);if (label.length) {this.setData({label,range,pickerValue});}} else {this.getAddressList().then(() => {this.setLabel();});}},// initRange方法用于初始化rangeinitRange() {if (!this.data.value.length) {const range = this.openChildren(this.data.addressList, [0, 0, 0]);this.setData({range});}},// getAddressList方法用于获取地址列表getAddressList() {return new Promise((resolve, reject) => {wx.getStorage({key: 'addressInfo',success: (res) => {this.setData({addressList: JSON.parse(res.data)});resolve();},fail: (err) => {reject(err);}});});},},
});

使用 wxml 文件

<picker-region bindchange="regionChange" placeholder="请选择所在区域" value="{{value}}" />

使用 js 文件

Page({data: {value: ""},regionChange(e) {console.log(e)},
})

模拟 json 数据格式

[{"value": "110000","label": "北京市","regionLevel": "1","parentRegionCode": "0","children": [{"value": "110100","label": "市辖区","regionLevel": "2","parentRegionCode": "110000","children": [{"value": "110101","label": "东城区","regionLevel": "3","parentRegionCode": "110100","children": null},{"value": "110118","label": "密云区","regionLevel": "3","parentRegionCode": "110100","children": null}]}]},{"value": "120000","label": "天津市","regionLevel": "1","parentRegionCode": "0","children": [{"value": "120100","label": "市辖区","regionLevel": "2","parentRegionCode": "120000","children": [{"value": "120101","label": "和平区","regionLevel": "3","parentRegionCode": "120100","children": null},{"value": "120102","label": "河东区","regionLevel": "3","parentRegionCode": "120100","children": null}]}]}
]

实现效果

在这里插入图片描述

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

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

相关文章

使用Linux docker方式快速安装Plik并结合内网穿透实现公网访问

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上传或者…

《视觉SLAM十四讲 从理论到实践(第2版)》

书中代码&#xff1a;GitHub - gaoxiang12/slambook2: edition 2 of the slambook 书籍PDF&#xff1a;关注【Learn from Zero】回复【SLAM142】即可领取

如何去掉Win10电脑右下角弹出来的广告?

如何去掉Win10电脑右下角弹出来的广告&#xff1f;在Win10电脑中&#xff0c;用户看到桌面右下角老是弹出来广告&#xff0c;特别影响用户自己的操作体验感。接下来小编给大家分享不同的关闭方法&#xff0c;操作后大家可以看到Win10电脑右下角不再出现广告。 具体去掉方法如下…

【蓝桥杯】二分查找

二分查找 题目描述 输入 n n n 个不超过 1 0 9 10^9 109 的单调不减的&#xff08;就是后面的数字不小于前面的数字&#xff09;非负整数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_{n} a1​,a2​,…,an​&#xff0c;然后进行 m m m 次询问。对于每次询问&#xff0c;给出一…

ClassNotFoundException: org.apache.hive.spark.client.Job

hive使用的是3.13版本&#xff0c;spark是3.3.3支持hadoop3.x hive将engine从mr改成spark&#xff0c;通过beeline执行insert、delete时一直报错&#xff0c;sparkTask rpc关闭&#xff0c; 查看yarn是出现ClassNotFoundException: org.apache.hive.spark.client.Job。 开始…

iOS17苹果备忘录怎么设置提醒?

在我们快节奏的生活中&#xff0c;苹果备忘录成了记录灵感、任务和重要事项的得力助手&#xff0c;面对着一个让人头疼的问题——备忘录竟然不能设置提醒&#xff01;突然感觉我的备忘录只是个寂寞的清单&#xff0c;没有提醒的陪伴。 于是&#xff0c;我着手寻找解决之道&…

数组逆序重放

数组逆序重放的意思是将数组的元素逆序排列&#xff0c;然后重新放回原数组中。这个操作可以在很多编程语言中实现&#xff0c;例如Python、Java等。 下面是一个Python的示例代码&#xff0c;可以实现这个操作&#xff1a; def reverse_and_rearrange(arr): # 反转数组 …

二维码智慧门牌管理系统升级解决方案:重新制牌审核快速审批

文章目录 前言一、快速审批与重新安装一、其他系统优势 前言 随着城市化进程的加速&#xff0c;门牌号码的管理变得日益重要。然而&#xff0c;传统的门牌管理方式已经无法满足现代社会的需求。在这样的背景下&#xff0c;二维码智慧门牌管理系统应运而生。但随着系统使用&…

LLM之RAG实战(一):使用Mistral-7b, LangChain, ChromaDB搭建自己的WEB聊天界面

一、RAG介绍 如何使用没有被LLM训练过的数据来提高LLM性能&#xff1f;检索增强生成&#xff08;RAG&#xff09;是未来的发展方向&#xff0c;下面将解释一下它的含义和实际工作原理。 ​ 假设您有自己的数据集&#xff0c;例如来自公司的文本文档。如何让ChatGPT和其他…

Golang使用Swagger文档教程

Golang开发效率是杠杠滴&#xff0c;简单几行代码就可完成一个可用的服务&#xff0c;如下代码&#xff1a; 采用Gin作为web framework采用Gorm作为持久化ORM采用Swagger作为OpenAPI文档管理工具 package mainimport ("encoding/csv""fmt""os"…

【Linux | 编程实践】防火墙 (网络无法访问)解决方案 Vim常用快捷键命令

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

LeetCode | 226. 翻转二叉树

LeetCode | 226. 翻转二叉树 OJ链接 不为空就翻转&#xff0c;空空就停止翻转左子树的节点给了右子树右子树的节点给了左就完成了翻转 struct TreeNode* invertTree(struct TreeNode* root) {//不为空就进行翻转if(root){//翻转struct TreeNode* tmp root->left;root->…

计算机网络安全问题分析与防护措施研究

计算机网络安全问题分析与防护措施研究 【摘要】在信息技术快速发展的今天&#xff0c;网络对于人类的生活方式影响显著增强&#xff0c;网络技术快速地在社会各个领域普及&#xff0c;使得计算机网络的安全成为一个亟待解决的问题。如何能够保证网络的快速健康发展己成为研究…

数据库之 redis

前言&#xff1a; 就学习爬虫而言&#xff0c;对于三种常见的数据库做个基本了解足以&#xff0c;所以笔记都是浅尝辄止&#xff0c;不会涉及太深入的东西。 redis简介 Redis&#xff08;Remote Dictionary Server &#xff0c;远程字典服务&#xff09; 是一个使用ANSI C编写…

简单可行的SeruatV4的安装方案

目前Seurat的版本从V4升级到了V5&#xff0c;由于一些变化&#xff0c;导致当年取巧&#xff0c;使用获取数据的方法都无法在V5中使用。 建议在操作前重启下Rstudio&#xff08;或更确切的说是R&#xff09;&#xff01;&#xff01;&#xff01; 那么如何确保自己能够安装V4的…

活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新

2023年11月28日&#xff0c;德州仪器(TI)嵌入式技术创新发展研讨会在上海顺利举办。作为TI中国第三方IDH&#xff0c;深圳市信驰达科技有限公司受邀参加&#xff0c;并设置展位&#xff0c;展出CC2340系列低功耗蓝牙模块及TPMS、蓝牙数字钥匙解决方案&#xff0c;与众多业内伙伴…

Vue框架学习笔记——列表渲染:v-for

文章目录 前文提要代码正文 前文提要 本人仅做个人学习记录&#xff0c;如有错误&#xff0c;请多包涵 主要学习链接&#xff1a;尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 代码正文 <body><div id"box"><ul><li v-for"(p,index)…

Synchronized关键字的底层原理

Synchronized实现 Synchronized创建的时候一个互斥的对象锁&#xff0c;每次只有一个线程可以获取该锁。 其底层主要是基于Monitor实现的&#xff0c;在对象的对象头中存储了MarkWord存储的就是Monitor的地址。 对象的内存结构 对象在内存中存储主要分为三个部分&#xff1a…

聊一聊大模型 | 京东云技术团队

事情还得从ChatGPT说起。 2022年12月OpenAI发布了自然语言生成模型ChatGPT&#xff0c;一个可以基于用户输入文本自动生成回答的人工智能体。它有着赶超人类的自然对话程度以及逆天的学识。一时间引爆了整个人工智能界&#xff0c;各大巨头也纷纷跟进发布了自家的大模型&#…

电动车刷卡-CI522方案

Ci522是一颗工作在13.56MHz频率下的非接触式读写芯片&#xff0c;支持读A卡&#xff08;CI523支持读A/B卡&#xff09;&#xff0c;可做智能门锁、电动车NFC一键启动、玩具NFC开锁等应用。为部分要求低成本&#xff0c;PCB小体积的产品提供了可靠的选择。 Ci522与Si522/MFRC52…