微信小程序实现收货地址城市选择效果(添加收货地址)

先来张效果图

这里主要是城市选择效果,请忽视其他,不要吐槽,谢谢

接下来看一下代码吧

wxml

<!--pages/my/my-add-address/index.wxml-->
<view class="redact-address">
  <view class="possess-layout">
    <view class="mains">
      <view class="address-msg">
        <view class="item-msg">收货人</view>
        <view class="section">
          <input type="text" placeholder="请填写收货人姓名" value="{{consigneeName}}" bindblur="consigneeNameInput" placeholder-class="phcolor"></input>
        </view>
        <view class="address-right">
          <image src="../../../img/icon/icon-add-address-user.png"></image>
        </view>
      </view>
      <view class="address-msg">
        <view class="item-msg">手机号码</view>
        <view class="section">
          <input type="number" placeholder="请填写收货人手机号码" value="{{phone}}" maxlength="11" bindblur="phoneInput" placeholder-class="phcolor"></input>
        </view>
      </view>
      <view class="address-msg">
        <view class="item-msg">所在地区</view>
        <view class="section" bindtap='select'>
          <input disabled="disabled" placeholder="省市区县、乡镇等" value="{{consigneeRegion}}" bindblur="consigneeRegionInput" placeholder-class="phcolor"></input>
        </view>
        <view class="address-rights" bindtap='select'>
          <image src="../../../img/icon/icon-site-location.png"></image>
          <view>定位</view>
        </view>
      </view>
      <view class="address-msg">
        <view class="item-msg">详细地址</view>
        <view class="section">
          <input type="text" placeholder="街道、楼牌号等" value="{{detailedAddress}}" bindblur="detailedAddressInput" placeholder-class="phcolor"></input>
        </view>
      </view>
      <view class="label">
        <view class="label-title">标签</view>
        <view class="label-list">
          <block wx:for="{{labelList}}" wx:key="index">
            <view class="labels {{labelDefault==index? 'labels-active': ''}}" data-index="{{index}}" bindtap="chooseLabelSelect">{{item}}</view>
          </block>
        </view>
      </view>
      <view class="default-setting">
        <view class="defaul-setting-left">
          <view>设置默认地址</view>
          <view>提醒:每次下单会默认推荐使用该地址</view>
        </view>
        <image class="defaul-setting-right" src="../../../img/icon/icon-off-by-default.png"></image>
      </view>
    </view>
  </view>
</view>

<view class="btn" bindtap="submit">保存</view>
    

<view class="picker" animation="{{animationAddressMenu}}" style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
  <view class="picker-view" animation="{{animationAddressMenu}}" style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
    <!-- 确认取消按钮 -->
    <view class='gangedBtn'>
      <text class="city-cancel" catchtap="cityCancel">取消</text>
      <text style="float: right" catchtap="citySure">确定</text>
    </view>
    <!-- 选择地址 -->
    <picker-view class='cont' bindchange="cityChange" value="{{value}}" wx:key="">
      <!-- 省 -->
      <picker-view-column>
        <view wx:for="{{provinces}}" class="picker-item" wx:key="index">{{item.name}}</view>
      </picker-view-column>
      <!-- 市 -->
      <picker-view-column>
        <view wx:for="{{citys}}" class="picker-item" wx:key="index">{{item.name}}</view>
      </picker-view-column>
      <!-- 区 -->
      <picker-view-column>
        <view wx:for="{{areas}}" class="picker-item" wx:key="index">{{item.name}}</view>
      </picker-view-column>
    </picker-view>
  </view>
</view>

wxss

/* pages/my/my-add-address/index.wxss */
.redact-address {
  background: white;
  margin-bottom: 20rpx;
}

.address-msg {
  height: 128rpx;
  display: flex;
  align-items: center;
  background: #FFFFFF;
  border-top: 2rpx solid #efefef;
  font-size: 28.68rpx;
  color: #333333;
  padding: 0 20rpx;
}
.address-right image {
  width: 32rpx;
  height: 32rpx;
}
.address-rights {
  display: flex;
  align-items: center;
}
.address-rights image {
  width: 26rpx;
  height: 32rpx;
  margin-right: 13rpx;
}
.address-rights view {
  font-size: 28.68rpx;
}
.address-msg:last-child {
  border-bottom: none;
}

.section {
  width: 58%;
}
.phcolor {
  color: #999999;
}
.item-msg {
  width: 25%;
  margin-right: 25rpx;
}

.img {
  width: 35rpx;
  height: 35rpx;
  align-self: center;
}

.address-right {
  width: 100rpx;
  display: flex;
  flex-direction: row-reverse;
}

/* 标签 */
.label {
  display: flex;
  height: 128rpx;
  align-items: center;
  margin-top: 73rpx;
  border-top: 1px solid #EEEEEE;
  border-bottom: 1px solid #EEEEEE;
  padding: 0 20rpx;
}
.label-title {
  font-size: 28.68rpx;
  color: #333333;
  margin-right: 83rpx;
}
.label .label-list {
  display: flex;
}
.label .label-list .labels{
  height: 40rpx;
  width: 96rpx;
  border: 1px solid #EEEEEE;
  margin-right: 37rpx;
  text-align: center;
  line-height: 40rpx;
  font-size: 24rpx;
  color: #000000;
  border-radius: 20rpx;
}
.labels-active {
  background: #F73C41 !important;
  color: #FFFFFF !important;
}
/* 默认设置 */
.default-setting {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 160rpx;
  padding: 0 20rpx;
}
.defaul-setting-left view:nth-child(1){
  font-size: 28.68rpx;
  color: #333333;
  margin-bottom: 25rpx;
}
.defaul-setting-left view:nth-child(2) {
  font-size: 20rpx;
  color: #333333;
}
.defaul-setting-right {
  height: 64rpx;
  width: 105rpx;
}

.btn {
  width: 680rpx;
  height: 88rpx;
  background: #F73C41;
  color: #FFFFFF;
  position: fixed;
  bottom: 55rpx;
  left: 35rpx;
  border-radius: 41.5rpx;
  font-size: 36rpx;
  text-align: center;
  line-height: 88rpx;
}

/* 城市选择 */
.picker {
  width: 100%;
  height: 100%;
  display: flex;
  z-index: 12;
  background-color: #fff;
  background: rgba(0, 0, 0, 0.2);
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: fixed;
  bottom: 0;
  left: 0rpx;
}
.picker-view {
  width: 100%;
  display: flex;
  z-index: 12;
  background-color: #fff;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: fixed;
  bottom: 0;
  left: 0rpx;
  height: 40vh;
  border-top-left-radius: 30rpx;
  border-top-right-radius: 30rpx;
}

.gangedBtn {
  border-top: 1px solid #efefef;
  border-top-left-radius: 30rpx;
  border-top-right-radius: 30rpx;
  width: 100%;
  height: 90rpx;
  padding: 0 66rpx;
  box-sizing: border-box;
  line-height: 90rpx;
  text-align: center;
  color: black;
  font-size: 0.8rem;
  display: flex;
  background: white;
  justify-content: space-between;
}

.cont {
  width: 100%;
  height: 389rpx;
}

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

.address {
  width: 100%;
  height: 90rpx;
  line-height: 90rpx;
  text-align: center;
  border-bottom: 1rpx solid #f1f1f1;
}
.city-cancel {
  color: gray;
}

js

// pages/my/my-add-address/index.js
var address = require("../../../js/mock.js");

var app = getApp()
Page({
  /**
    * 控件当前显示的数据
    * provinces:所有省份
    * citys 选择省对应的所有市,
    * areas 选择市对应的所有区
    * consigneeRegion:点击确定时选择的省市县结果
    * animationAddressMenu:动画
    * addressMenuIsShow:是否可见
    */
  /**
   * 页面的初始数据
   */
  data: {
    animationAddressMenu: {},
    addressMenuIsShow: false,
    value: [0, 0, 0],
    provinces: [],
    citys: [],
    areas: [],
    consigneeName: "", 
    phone: "",
    consigneeRegion: "",
    detailedAddress: "",
    labelList: ["家", "公司", "学校"],            //标签
    labelDefault: 0,              // 标签默认,

    
  },
  consigneeNameInput: function(e) {
    
    this.setData({
      consigneeName: e.detail.value
    })
  },
  phoneInput: function(e) {
    
    this.setData({
      phone: e.detail.value
    })
  },
  consigneeRegionInput: function (e) {
   
    this.setData({
      consigneeRegion: e.detail.value
    })
  },
  detailedAddressInput: function (e) {
    this.setData({
      detailedAddress: e.detail.value
    })
  },
  chooseLabelSelect: function(e) {
    var index = e.currentTarget.dataset.index;
    this.setData({
      labelDefault: index
    })
  },
  submit: function() {
    var consigneeName = this.data.consigneeName;
    console.log(consigneeName)
    var phone = this.data.phone;
    console.log(phone)
    var consigneeRegion = this.data.consigneeRegion;
    console.log(consigneeRegion)
    var detailedAddress = this.data.detailedAddress
    console.log(detailedAddress)
    if (consigneeName == "") {
      wx: wx.showToast({
        title: '请输入姓名',
        image: "../../../img/icon/icon-reminder.png"
      })
      return false
    }
    else if (phone == "") {
      wx: wx.showToast({
        title: '请输入手机号码',
        image: "../../../img/icon/icon-reminder.png"
      })
      return false
    }
    else if (consigneeRegion == "") {
      wx: wx.showToast({
        title: '请选择所在地区',
        image: "../../../img/icon/icon-reminder.png"
      })
      return false
    }
    else if (detailedAddress == "") {
      wx: wx.showToast({
        title: '请输入详细地址',
        image: "../../../img/icon/icon-reminder.png"
      })
      return false
    }
    else {
      wx.navigateTo({
        url: '../../my/my-delivery-address/index',
      })
    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 默认联动显示北京
    var id = address.provinces[0].id
    this.setData({
      provinces: address.provinces,
      citys: address.citys[id],
      areas: address.areas[address.citys[id][0].id],
    })
  },
  // 点击所在地区弹出选择框
  select: function (e) {
    // 如果已经显示,不在执行显示动画
    if (this.data.addressMenuIsShow) {
      return false
    } else {
      // 执行显示动画
      this.startAddressAnimation(true)
    }
  },
  // 执行动画
  startAddressAnimation: function (isShow) {
    if (isShow) {
      // vh是用来表示尺寸的单位,高度全屏是100vh
      this.animation.translateY(0 + 'vh').step()
    } else {
      this.animation.translateY(40 + 'vh').step()
    }
    this.setData({
      animationAddressMenu: this.animation.export(),
      addressMenuIsShow: isShow,
    })
  },
  // 点击地区选择取消按钮
  cityCancel: function (e) {
    this.startAddressAnimation(false)
  },
  // 点击地区选择确定按钮
  citySure: function (e) {
    var that = this
    var city = that.data.city
    var value = that.data.value
    this.startAddressAnimation(false)
    // 将选择的城市信息显示到输入框
    var consigneeRegion = that.data.provinces[value[0]].name + '-' + that.data.citys[value[1]].name + '-' + that.data.areas[value[2]].name
    that.setData({
      consigneeRegion: consigneeRegion,
    })
  },
  // 处理省市县联动逻辑
  cityChange: function (e) {
    var value = e.detail.value
    var provinces = this.data.provinces
    var citys = this.data.citys
    var areas = this.data.areas
    var provinceNum = value[0]
    var cityNum = value[1]
    var countyNum = value[2]
    // 如果省份选择项和之前不一样,表示滑动了省份,此时市默认是省的第一组数据,
    if (this.data.value[0] != provinceNum) {
      var 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) {
      // 滑动选择了第二项数据,即市,此时区显示省市对应的第一组数据
      var id = citys[cityNum].id
      this.setData({
        value: [provinceNum, cityNum, 0],
        areas: address.areas[citys[cityNum].id],
      })
    } else {
      // 滑动选择了区
      this.setData({
        value: [provinceNum, cityNum, countyNum]
      })
    }
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    var animation = wx.createAnimation({
      duration: 500,
      timingFunction: 'linear',
    })
    this.animation = animation
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

需要mock.js源码可自行扫码下载,

 

有时候比较忙, 可能在大家需要mock.js源码的时候, 我没能及时回复, 我在这里给大家说声抱歉, 我把mock源码上传到csdn了, 我没及时回复, 大家可以自行下载

微信小程序实现收货地址城市选择效果mock.js_微信小程序加收货地址-互联网文档类资源-CSDN下载

评论 79
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值