uniapp自定义picker城市多级联动组件

  • 支持多端——h5、app、微信小程序、支付宝小程序...
  • 支持自定义配置picker插件级数
  • 支持无限级

注意事项:插件传入数据格式为children树形格式,内部包含:id、name

参数 类型 描述 默认值 必选
title string 标题 ‘’
layer number 控制几级联动 1
data arr 数据 如:[{text: ‘’, adcode: ‘’, children: [{text: ‘’, adcode: ‘’}]}] []

组件运行图示:

组件选择后返回数据如:

引用示例:

<template><view class="content"><view class="aui-content" :style="{height: contentHeight}">   <view class="aui-btn aui-btn-blue" @click.stop="showPicker($event)">picker无限级联动</view>   </view><aui-picker ref="picker" :title="auiPicker.title":layer="auiPicker.layer":data="auiPicker.data"@callback="pickerCallback"></aui-picker></view>
</template><script>import auiPicker from '@/components/aui-picker/aui-picker.vue';export default {components: {auiPicker},data() {return {auiPicker: {title: 'picker多级联动',layer: null,data: []},}},created(){},mounted() {},methods: {//显示picker多级联动弹窗showPicker(e){const _this = this;_this.auiPicker.data=[{id: "1001",name: "一级菜单1",children: [{id: "1002",name: "二级菜单1-1",children: [{id: "1003",name: "三级菜单1-1",children: [{id: "1004",name: "四级菜单1-1"}]}]}]},{id: "1005",name: "一级菜单2",children: [{id: "1006",name: "二级菜单2-1",children: [{id: "1007",name: "三级菜单2-1",children: [{id: "1008",name: "四级菜单2-1"}]}]}]}];_this.$refs.picker.open().then(function(){console.log('picker打开');});},//picker多级联动回调pickerCallback(e){const _this = this;console.log(e);let result = '';e.data.forEach(function(item, index){result += item.name + '   ';});uni.showModal({title: '提示',content: result,success: function (res) {if (res.confirm) {console.log('用户点击确定');} else if (res.cancel) {console.log('用户点击取消');}}});}}}
</script><style>.aui-content{padding: 15px 0 0 0;}
</style>

aui-picker组件完整代码:

项目components文件夹下创建aui-picker夹,此文件夹下创建aui-picker.vue——多级联动组件

<template name="aui-picker"><view class="aui-picker" v-if="SHOW" :class="{'aui-picker-in': FADE==1,'aui-picker-out': FADE==0}"><view class="aui-mask" @click.stop="close"></view><view class="aui-picker-main"><view class="aui-picker-header"><view class="aui-picker-title" v-if="title">{{title}}</view><view class="aui-picker-close iconfont iconclose" @click.stop="close"></view></view><view class="aui-picker-nav"><view class="aui-picker-navitem"v-if="nav.length>0"v-for="(item, index) in nav" :key="index" :data-index="index" :class="[index==navCurrentIndex ? 'active' : '', 'aui-picker-navitem-'+index]" :style="{margin: nav.length>2 ? '0 10px 0 0' : '0 30px 0 0'}"@click.stop="_changeNav($event)">{{item.name}}</view>              <view class="aui-picker-navitem"                                  :key="nav.length" :data-index="nav.length":class="[nav.length==navCurrentIndex ? 'active' : '', 'aui-picker-navitem-'+nav.length]" :style="{margin: nav.length>2 ? '0 10px 0 0' : '0 30px 0 0'}"@click.stop="_changeNav($event)">请选择</view><view class="aui-picker-navborder" :style="{left: navBorderLeft+'px'}"></view></view><view class="aui-picker-content"><view class="aui-picker-lists"><view class="aui-picker-list"v-for="(list, index) in queryItems.length + 1":key="index" :data-index="index" :class="[index==navCurrentIndex ? 'active' : '']"><view class="aui-picker-list-warp" v-if="index == 0"><view class="aui-picker-item" v-for="(item, key) in items" v-if="item.pid=='0'":key="key":data-pindex="index":data-index="key":data-id="item.id" :data-pid="item.pid":data-name="item.name":class="{'active': result.length>index && result[index].id==item.id}":style="{'background': touchConfig.index==key && touchConfig.pindex==index ? touchConfig.style.background : ''}"@click.stop="_chooseItem($event)"@touchstart="_btnTouchStart($event)"@touchmove="_btnTouchEnd($event)"@touchend="_btnTouchEnd($event)">{{item.name}}</view></view><view class="aui-picker-list-warp" v-else><view class="aui-picker-item" v-for="(item, key) in queryItems[index-1]":key="key":data-pindex="index":data-index="key":data-id="item.id":data-pid="item.pid":data-name="item.name":class="{'active': result.length>index && result[index].id==item.id}":style="{'background': touchConfig.index==key && touchConfig.pindex==index ? touchConfig.style.background : ''}"@click.stop="_chooseItem($event)"@touchstart="_btnTouchStart($event)"@touchmove="_btnTouchEnd($event)"@touchend="_btnTouchEnd($event)">{{item.name}}</view></view></view></view></view></view></view>
</template><script>export default {name: 'aui-picker',props: {title: { //标题type: String,default: ''},layer: { //控制几级联动,默认无限级(跟随数据有无下级)type: Number,default: null},data: { //数据 如:[{id: '', name: '', children: [{id: '', name: ''}]}]type: Array,default (){return [// [{id: '', name: '', children: [{id: '', name: ''}]}]]}}},data(){return {SHOW: false,FADE: -1,nav: [],items: [],queryItems: [],navCurrentIndex: 0,navBorderLeft: 40,result: [],touchConfig: {index: -1,pindex: -1,style: {color: '#197DE0',background: '#EFEFEF'} }}},created(){const _this = this;},watch:{data(){const _this = this;const data = _this.data;_this.items = _this._flatten(data, '0')}  },mounted(){},methods:{// 打开open(){const _this = this;              _this.reset(); //打开时重置pickerreturn new Promise(function(resolve, reject){_this.SHOW = true;_this.FADE = 1;resolve();});},// 关闭close(){const _this = this;return new Promise(function(resolve, reject){_this.FADE = 0;const _hidetimer = setTimeout(()=>{_this.SHOW = false;_this.FADE = -1;clearTimeout(_hidetimer);resolve();                       },100)  });},//重置reset(){const _this = this;_this.queryItems = [];_this.nav = [];_this.navBorderLeft = 40;_this.navCurrentIndex = 0;_this.result = [];},//导航栏切换_changeNav(e){const _this = this;const index = Number(e.currentTarget.dataset.index);_this.navCurrentIndex = index;const _el = uni.createSelectorQuery().in(this).select(".aui-picker-navitem-"+index);_el.boundingClientRect(data => {_this.navBorderLeft = data.left + 20;}).exec();},//数据选择_chooseItem(e){const _this = this;const id = e.currentTarget.dataset.id;const name = e.currentTarget.dataset.name;const pid = e.currentTarget.dataset.pid;const _arr = [];_this.result[_this.navCurrentIndex] = {id: id, name: name, pid: pid};if((!_this._isDefine(_this.layer) && _this._isDefine(_this._deepQuery(_this.data, id).children)) || (_this.navCurrentIndex < (Number(_this.layer) - 1) && _this._isDefine(_this._deepQuery(_this.data, id).children))){ //有下级数据_this._deepQuery(_this.data, id).children.forEach(function(item, index){_arr.push({id: item.id, name: item.name, pid: id});});if(_this.navCurrentIndex == _this.queryItems.length){ //选择数据_this.queryItems.push(_arr);_this.nav.push({name: name});}else{ //重新选择数据_this.queryItems.splice(_this.navCurrentIndex+1, 1);_this.nav.splice(_this.navCurrentIndex+1, 1);_this.queryItems.splice(_this.navCurrentIndex, 1, _arr);_this.nav.splice(_this.navCurrentIndex, 1, {name: name});}_this.navCurrentIndex = _this.navCurrentIndex + 1;const _el = uni.createSelectorQuery().in(this).select(".aui-picker-navitem-"+_this.navCurrentIndex);setTimeout(()=>{_el.boundingClientRect(data => {_this.navBorderLeft = data.left + 20;}).exec();},100)}else{ //无下级数据_this.close().then(()=>{_this.$emit("callback", {status: 0, data: _this.result});});}},          //递归遍历——将树形结构数据转化为数组格式_flatten(tree, pid) {return tree.reduce((arr, {id, name, children = []}) =>arr.concat([{id, name, pid}], this._flatten(children, id)), [])},//根据id查询对应的数据(如查询id=10100对应的对象)_deepQuery(tree, id) {let isGet = false;let retNode = null;function deepSearch(tree, id){for(let i = 0; i < tree.length; i++) {if(tree[i].children && tree[i].children.length > 0) {deepSearch(tree[i].children, id);}if(id === tree[i].id || isGet) {isGet||(retNode = tree[i]);isGet = true;break;}}}deepSearch(tree, id);return retNode;},/***判断字符串是否为空@param {string} str 变量@example: aui.isDefine("变量");*/_isDefine(str){if (str==null || str=="" || str=="undefined" || str==undefined || str=="null" || str=="(null)" || str=='NULL' || typeof (str)=='undefined'){return false;}else{str = str + "";str = str.replace(/\s/g, "");if (str == ""){return false;}return true;}},_btnTouchStart(e){const _this = this,index = Number(e.currentTarget.dataset.index),pindex = Number(e.currentTarget.dataset.pindex);_this.touchConfig.index = index;_this.touchConfig.pindex = pindex;},_btnTouchEnd(e){const _this = this,index = Number(e.currentTarget.dataset.index),pindex = Number(e.currentTarget.dataset.pindex);_this.touchConfig.index = -1;_this.touchConfig.pindex = -1;},  }}
</script><style scoped>/* ====================多级联动弹窗=====================*/.aui-picker{width: 100vw;height: 100vh;opacity: 0;      position: fixed;top: 0;left: 0;z-index: 999;/* display: none; */}.aui-picker.aui-picker-in{-moz-animation: aui-fade-in .1s ease-out forwards;-ms-animation: aui-fade-in .1s ease-out forwards;-webkit-animation: aui-fade-in .1s ease-out forwards;animation: aui-fade-in .1s ease-out forwards;}.aui-picker.aui-picker-out{-moz-animation: aui-fade-out .1s ease-out forwards;-ms-animation: aui-fade-out .1s ease-out forwards;-webkit-animation: aui-fade-out .1s ease-out forwards;animation: aui-fade-out .1s ease-out forwards;}.aui-picker-main{width: 100vw;height: 50vh;background: #FFF;border-radius: 15px 15px 0 0;position: absolute;left: 0px;bottom: -50vh;      z-index: 999;}.aui-picker.aui-picker-in .aui-picker-main{-moz-animation: aui-slide-up-screen .2s ease-out forwards;-ms-animation: aui-slide-up-screen .2s ease-out forwards;-webkit-animation: aui-slide-up-screen .2s ease-out forwards;animation: aui-slide-up-screen .2s ease-out forwards;}.aui-picker.aui-picker-out .aui-picker-main{-moz-animation: aui-slide-down-screen .2s ease-out forwards;-ms-animation: aui-slide-down-screen .2s ease-out forwards;-webkit-animation: aui-slide-down-screen .2s ease-out forwards;animation: aui-slide-down-screen .2s ease-out forwards;}.aui-picker-header{width: 100%;min-height: 50px;position: relative;z-index: 999;background: #F2F2F2;border-radius: 15px 15px 0 0;}.aui-picker-header::after{content: '';width: 100%;height: 1px;background: rgba(100,100,100,.3);-moz-transform: scaleY(.3);-ms-transform: scaleY(.3);-webkit-transform: scaleY(.3);transform: scaleY(.3);position: absolute;left: 0;bottom: 0;z-index: 999;}.aui-picker-title{line-height: 20px;text-align: center;font-size: 17px;color: #333;padding: 15px;box-sizing: border-box;position: absolute;left: 50px;right: 50px;top: 0;}.aui-picker-close.iconfont{width: 50px;height: 50px;line-height: 50px;text-align: center;font-size: 20px;color: #aaa;border-radius: 0 10px 0 0;position: absolute;right: 0;top: 0;}.aui-picker-content{width: 100%;height: -webkit-calc(100% - 100px);height: calc(100% - 100px);}.aui-picker-nav{width: 100%;height: 50px;text-align: left;padding: 0 20px;margin: 0 0 1px 0;justify-content: flex-start;white-space: nowrap;box-sizing: border-box;position: relative;}.aui-picker-nav::after{content: '';width: 100%;height: 1px;background: rgba(100,100,100,.3);-moz-transform: scaleY(.3);-ms-transform: scaleY(.3);-webkit-transform: scaleY(.3);transform: scaleY(.3);position: absolute;left: 0;bottom: 0;z-index: 999;}.aui-picker-navitem{width: 80px;line-height: 50px;font-size: 16px;margin: 0 30px 0 0;text-align: center;display: inline-block;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}.aui-picker-navitem.active{color: #197DE0;}.aui-picker-navborder{width: 40px;height: 3px;background: #197DE0;border-radius: 5px;transition: left .15s;position: absolute;left: 40px;bottom: 0;}.aui-picker-lists{width: 100%;height: 100%;justify-content: space-around;white-space: nowrap;}.aui-picker-list{width: 100%;height: 100%;overflow: hidden;overflow-y: scroll;display: none;vertical-align: top;}.aui-picker-list.active{display: inline-block;}.aui-picker-list-warp{width: 100%;height: auto;box-sizing: border-box;padding: 15px 0;display: inline-block;}.aui-picker-item{width: 100%;height: 50px;line-height: 50px;padding: 0 15px;box-sizing: border-box;font-size: 15px;color: #333;position: relative;}.aui-picker-item.active{color: #197DE0;}.aui-picker-item.active::after{content: '✔';font-size: 15px;color: #197DE0;position: absolute;top: 0px;right: 10px;}</style>

uniapp自定义picker城市多级联动组件相关推荐

  1. picker封装 uniapp_uniapp自定义picker城市多级联动组件

    uniapp自定义picker城市多级联动组件 支持多端--h5.app.微信小程序.支付宝小程序... 支持自定义配置picker插件级数 支持无限级 注意事项:插件传入数据格式为children树 ...

  2. 使用React实现选择城市三级联动组件

    以下代码是初期写的代码,后来对代码进行优化,解决了初期的bug.完整的选择城市三级联动组件可以参考我的github项目中的代码,这是后期调试成功上传上去的React选择城市三级联动组件 <Sel ...

  3. vue城市三级联动组件 vue-area-linkage

    Install the pkg with npm: // v5之前的版本 npm i --save vue-area-linkage// v5及之后的版本 npm i --save vue-area- ...

  4. picker多选 vant_Vant picker 多级联动操作

    官网地址:链接 官网文档可能不是很完善,但仔细看文档,方法,类型其实都讲到的. 度娘也没有找到,花了大半天爬坑试错. 搭配弹出层使用 const citys = [ // 我们习惯的格式. 可以后台给 ...

  5. 微信小程序—自定义(城市选择)弹窗组件,将弹窗组件的值传给调用页面并显示(图文)

    微信小程序-自定义(城市选择)弹窗组件,并传值 1.新建component文件夹用来存放自定义组件,并在其文件夹内新建cityModal Component,注意不是新建Page 新建完成之后出现四个 ...

  6. vue\uniapp自定义活动倒计时组件

    vue\uniapp自定义活动倒计时组件 效果 调用组件时传递的 timeData的属性type_id:名称,begin_time:开始时间(时间戳)end_time:结束时间(时间戳) 组件代码 & ...

  7. uniapp “未检测到手机或模拟器,请稍后重试”和uniapp自定义组件与通信

    错误九:"未检测到手机或模拟器,请稍后重试" 在使用HBuilderX创建uni-app项目的时候想要在手机上运行看看效果,当你点击运行下面的"运行到手机或模拟器(N)& ...

  8. 微信小程序自定义picker弹框组件

    要有遥不可及的梦想,也要有脚踏实地的本事.----------- Grapefruit.Banuit Gang(香柚帮) 柚子写项目遇到了一个问题,就是微信小程序官方文档上面的弹框组件picker,它 ...

  9. vue 学科年级学段多级联动需求 跨组件如何监听 如何解决vue-communicatio监听多个参数的问题 以及vue-communicatio的注意事项

    最近的项目中有这么一个需求 先解释一下需求 顶部是一个多级联动的组件,用来选择学段,年级和科目,同时左侧的教材和知识点的树形结构受到顶部三个字段的影响,随之变动而变动 顶部的联动解决方案是使用 wat ...

最新文章

  1. 如何优化才能赢得搜索引擎“欢心”,提升抓取量?
  2. 安装python程序后要进行什么设置-安装好Pycharm后如何配置Python解释器简易教程...
  3. 《Groovy语言规范》-语法(三)
  4. aspnet还有人用吗_别盲目跟风!理性分析:超火的小香风外套真的适合你吗?
  5. c语言gets与fgetc,区分C语言中getch、getche、fgetc、getc、getchar、fgets、gets 转
  6. mac自己定义tree命令
  7. OEA中的缓存模块设计
  8. 敏捷开发用户故事系列之五:用户故事的分类
  9. Oracle+PL+SQL从入门到精通.丁士锋.清华大学出版社.2012
  10. 程序员:如何成为一个全栈的工程师? 1
  11. 开发Windows物流管理系统——(一)前期准备
  12. 求职类App原型制作分享-Part-time Clouds
  13. MATLAB如何导出高分辨率的模型图片、PDF
  14. Matlab分号的使用
  15. pubwin扫描安装
  16. 分布式身份认证——未来信任生态的基石
  17. HDMI转DP带5V供电转接线方案|HDMI转EDP点屏转换方案|CS5801最新电路设计原理图
  18. 钉钉直播教学中遇到的26个常见问题解决方法
  19. 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰
  20. 持续集成(第二版) Martin Fowler著

热门文章

  1. android图片视频图片封装,Android中的图片截屏和视频截屏
  2. 评析春江花月夜(River in spring and beautiful moon)
  3. 小企鹅输入法 安装 设置 支持中文 for ubuntu 10.04
  4. android 布局圆形_Android约束布局–圆形定位
  5. Redis实战——优惠券秒杀(超卖问题)
  6. 【 LDO 精密低压差稳压器(详细参数说明)multisim仿真】
  7. 数字化时代,企业运维面临现状及挑战分析解读
  8. IOS开发之----资源汇总
  9. centos7 Minimal 虚拟机安装图文教程
  10. linux下串口调试工具