1. 程式人生 > >微信小程式自定義元件實現地址單級連續選擇(拼多多APP地址選擇樣式)

微信小程式自定義元件實現地址單級連續選擇(拼多多APP地址選擇樣式)

最終效果
在這裡插入圖片描述
在這裡插入圖片描述
首先在page資料夾下建立components資料夾,在components資料夾下建立region-picker的資料夾,然後在region-picker資料夾下建立Component名稱為region-picker。

region-picker.js

/* region-picker.js */
import area from '../../../utils/area.js';
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中的資料 console.log('123123123') 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

<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="/../imgs/s.png"
                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: 40rpx;
  height: 40rpx;
  border: 1px solid green;
}

.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;
}

region-picker.json

{
  "component": true,
  "usingComponents": {}
}

這個元件到此就已經寫完了,如何引用呢
在page資料夾下建立rmb資料夾,然後建立page命名為rmb。

rmb.js

/* 頁面的 js */
Page({
  data: {
    regionValue: [],
    showRegion: false,
  },
  chooseRegion: function (e) {
    console.log('123')
    console.log(e)
    this.setData({
      showRegion: true,
    });
  },
  emitHideRegion: function (e) {
    this.setData({
      showRegion: e.detail.showRegion,
      regionValue: e.detail.regionValue,
    });
  },
});

rmb.json

{
  "usingComponents": {
    "region-picker": "../components/region-picker/region-picker"
  }
}

rmb.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>

area.js
有些地址重複了,等我修復一下就發上來,QQ:961052877