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

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

作者: 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