美文网首页
微信小程序的定义省市区联动组件

微信小程序的定义省市区联动组件

作者: xiesen | 来源:发表于2020-08-11 15:59 被阅读0次

    作者:https://www.jianshu.com/p/58ebcbaf2906

    最终效果

    image

    思维导图

    image

    自定义region-picker组件

    region-picker.js文件

    const addressRequest = require('../../../http/address.js')
    const utils = require('../../../utils/utils')
    Component({
      lifetimes: {
        attached: function () {
          if(this.properties.regionValue.length == 0){
            this.getChildArea(2, "1")
          }
        },
       
      },
      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,
              });
              if(this.data.region.select == 0){
                this.getChildArea(2, "1")
              }else if(this.data.region.select == 1){
                this.getChildArea(3, this.data.region.tabs[this.data.region.select-1].id)
              }else if(this.data.region.select == 2){
                this.getChildArea(4, this.data.region.tabs[this.data.region.select-1].id)
              }
            }
          },
        },
      },
      data: {
        dialog: false,
        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);
        },
        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,
            });
            // 获取子选项
            
            if(this.data.region.select == 0){
              this.getChildArea(2, "1")
            }else if(this.data.region.select == 1){
              this.getChildArea(3, this.data.region.tabs[this.data.region.select-1].id)
            }else if(this.data.region.select == 2){
              this.getChildArea(4, this.data.region.tabs[this.data.region.select-1].id)
            }
          } else {
            // 三级选项选择完毕关闭省市区选择器
            this.emitHideRegion();
          }
        },
        getChildArea: function(type, id) {
          //请求数据(你也可以在本地定义一个json文件或者地址信息,这里是对地址数据的操作)
          this.setData({
            area: []
          })
          addressRequest.getPca({fatherRegionCode: id, regionType: type}, (data)=>{
            wx.hideLoading();
            if (data.code != 200) {
              utils.showToast(data.msg, "loading", 1000);
              return;
            }
            this.setData({
              area: data.data
            })
          })
        },
        // 省市区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,
          });
          if(this.data.region.select == 0){
            this.getChildArea(2, "1")
          }else if(this.data.region.select == 1){
            this.getChildArea(3, this.data.region.tabs[this.data.region.select-1].id)
          }else if(this.data.region.select == 2){
            this.getChildArea(4, this.data.region.tabs[this.data.region.select-1].id)
          }
        },
      },
    });
    

    region-picker.wxml文件

    <!--pages/components/qca/qca.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>
              
          </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="id"
                          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.regionCode}}"
                          data-name="{{item.regionName}}"
                          bindtap="bindRegionChange">
                          {{item.regionName}}
                      </view>
                  </scroll-view>
              </view>
          </view>
      </view>
    </view>
    

    region-picker.wxss文件

    /* pages/components/qca/qca.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: #2E4AE7;
    }
    .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文件

    <view class="cu-form-group" style="padding: 0rpx">
      <view class="title">地址选择</view>
      <view bindtap="chooseRegion" wx:if="{{!regionValue[0].id}}" style="color: #999999;">请选择地址 <image class="address-image" src="../images/stock/arrows.png"></image> </view>
        <view bindtap="chooseRegion" wx:else style="margin-right: 10rpx;">
            <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>
            <image class="address-image" src="../images/publicImg/guidance.png"></image>
        </view>
    </view>
    <region-picker
      region-value="{{regionValue}}"
      show-region="{{showRegion}}"
      bind:myevent="emitHideRegion">
    </region-picker>
    

    使用组件页面的 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,
        });
      },
    });
    

    使用组件页面的 json文件

    {
      "usingComponents": {
        "region-picker": "region-picker组件的路径"
      }
    }
    

    相关文章

      网友评论

          本文标题:微信小程序的定义省市区联动组件

          本文链接:https://www.haomeiwen.com/subject/ojlydktx.html