zoukankan      html  css  js  c++  java
  • (转)个微信小程序的省市区选择器

     
    最终效果

    思维导图

     
    思维导图

    主要代码

    组件 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>
                <image
                    src="自行替换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">
                        <view
                            class="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">
                        <view
                            class="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-picker
        region-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: '...'
            }, ...]
        }, ...]
    }, ...]
    

    有疑问戳微信小程序官方文档

     


    链接:https://www.jianshu.com/p/58ebcbaf2906

  • 相关阅读:
    缺陷管理、分类、提交
    selenium2.0处理case实例(二)
    Robot Framework自动化测试(六)--- robotremoteserver使用
    Robot Framework自动化测试(五)--- 开发系统关键字
    Robot Framework自动化测试(四)--- 分层思想
    Robot Framework自动化测试(三)---Selenium API
    Robot Framework自动化测试(二)---元素定位
    Robot Framework自动化测试(一)---第一个脚本
    python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告
    Python 基于http接口自动化测试
  • 原文地址:https://www.cnblogs.com/zmdComeOn/p/12658203.html
Copyright © 2011-2022 走看看