天天看点

微信小程序自定义组件(1)----地址选择器

话不多说,先上效果图:

实现代码:

wxml

<view class="address-selecter">
  <text class='chooseAddress_text' bindtap='selectDistrict'>{{address}}</text>
  <view class="picker-view" animation="{{animationAddressMenu}}" 
  style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
  <view style="height:10% ;width:95%;margin-top:10rpx">
    <text catchtap="cityCancel" class='cancel_text'>取消</text>
    <text style="float: right" catchtap="citySure" class='sure_text'>确定</text>
  </view>
  <picker-view style="width: 100%; height: 300px;" bindchange="_cityChange" value="{{value}}" >
    <picker-view-column>
      <view wx:for="{{provinces}}" class="picker-item" wx:key="*this">
        {{item.name}}</view>
    </picker-view-column>
    <picker-view-column>
      <view wx:for="{{citys}}" class="picker-item" wx:key="*this">
        {{item.name}}</view>
    </picker-view-column>
    <picker-view-column>
      <view wx:for="{{areas}}" class="picker-item" wx:key="*this">
        {{item.name}}</view>
    </picker-view-column>
  </picker-view>
</view>
</view>      

wxss

.chooseAddress_text{
  margin-left: 20rpx;
  font-size: 30rpx;
  text-align: center;
}

.picker-view {
  width: 100%;
  display: flex;
  z-index:12;
  background-color: #fff;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: fixed;
  bottom: 0rpx;
  left: 0rpx;
  height: 40vh;
}

.picker-item {
  line-height: 70rpx;
  margin-left: 5rpx;
  margin-right: 5rpx;
  text-align: center;
}

.picker-view .cancel_text{
  color: green;
}

.picker-view .sure_text{
  color: green;
}      

json

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

js

var util = require("../../utils/util.js")
var address = require('../../utils/city.js')

Component({
  /**
   * 组件的属性列表
   */
  properties: {
   address:{
     type: String,
     value: '点击选择地址'
   }
  },

  /**
   * 组件的初始数据
   */
  data: {
    animation: {},
    animationAddressMenu: {},
    addressMenuIsShow: false,
    value: [0, 0, 0],
    provinces: [],
    citys: [],
    areas: [],
    address: '',
  },

  /**
   * 生命周期函数
   */
  lifetimes:{
    attached: function () {
      let id = address.provinces[0].id
      this.setData({
        provinces: address.provinces,
        citys: address.citys[id],
        areas: address.areas[address.citys[id][0].id],
      })
    },
  },

  /**
   * 组件的方法列表
   */
  methods: {
    /**
   * 点击所在地区弹出选择框
   */
    selectDistrict: function (e) {
      var that = this
      if (that.data.addressMenuIsShow) {
        return
      }
      that._startAddressAnimation(true)
    },

    /**
     * 取消按钮
     */
    cityCancel: function (e) {
      this._startAddressAnimation(false)
    },

    /**
     * 确定按钮
     */
    citySure: function (e) {
      var that = this
      let value = that.data.value
      that._startAddressAnimation(false)
      // 所选择的城市信息
      let address_now = that.data.provinces[value[0]].name +
       ',' + that.data.citys[value[1]].name + ',' + that.data.areas[value[2]].name
      console.log(address_now)
      that.setData({
        address: address_now
      })
      that.triggerEvent('select', [address_now, that.data.provinces[value[0]].name,
        that.data.citys[value[1]].name, that.data.areas[value[2]].name])
    },

    /**
     * 执行动画
     */
    _startAddressAnimation: function (isShow) {
      var that = this
      if (isShow) {
        that.animation = wx.createAnimation({
          duration: 1000,
          timingFunction: 'ease',
        }),
        that.animation.translateY(0 + 'vh').step()
      } else {
        that.animation.translateY(40 + 'vh').step()
      }
      that.setData({
        animationAddressMenu: that.animation.export(),
        addressMenuIsShow: isShow,
      })
    },

    /**
     * 点击蒙版时取消组件的显示
     */
    _hideCitySelected: function (e) {
      this._startAddressAnimation(false)
    },


    /**
     * 处理省市县联动逻辑
     */
    _cityChange: function (e) {
      let value = e.detail.value
      let provinces = this.data.provinces
      let citys = this.data.citys
      let areas = this.data.areas
      let provinceNum = value[0]
      let cityNum = value[1]
      let countyNum = value[2]
      // 如果省份选择项和之前不一样,表示滑动了省份,此时市默认是省的第一组数据,
      if (this.data.value[0] != provinceNum) {
        let id = provinces[provinceNum].id
        this.setData({
          value: [provinceNum, 0, 0],
          citys: address.citys[id],
          areas: address.areas[address.citys[id][0].id],
        })
      } else if (this.data.value[1] != cityNum) {
        // 滑动选择了第二项数据,即市,此时区显示省市对应的第一组数据
        let id = citys[cityNum].id
        this.setData({
          value: [provinceNum, cityNum, 0],
          areas: address.areas[citys[cityNum].id],
        })
      } else {
        // 滑动选择了区
        this.setData({
          value: [provinceNum, cityNum, countyNum]
        })
      }
    },

  }
})      

使用方式:

<!--地址-->
 <view class="address">
    <text class='address_text'>地址:</text>
    <address-selecter bind:select="addressSelecter"></address-selecter>
 </view>      
/**
   * 地址选择
   */
  addressSelecter(e){
   console.log(e)
  },      

必要文件下载地址

继续阅读