微信小程序商城项目实战(第九篇:收货地址管理)

收货地址管理

  • 收购地址查询
    • 分析
    • 代码实现
      • 效果图展示
  • 新增收货地址
    • 分析
    • 代码实现
      • 效果图

收购地址查询

分析

  • 顶部改为"管理收货地址"
  • 中部为收货地址+单选按钮(用与设为默认收货地址,编辑删除没做(简单不想做hh)
  • 下方为添加新地址

代码实现

改变顶部导航内容"navigationBarTitleText": "管理收货地址"
界面:

<radio-group bindchange="radioChange">
<view class='list-item' wx:for="{{addressList}}" wx:key="index">
<view class='item-head'>
    <text>{{item.label}}text>
    <text class='right'>{{item.tel}}text>
view>

<view class='item-desc'>
   <text>{{item.city}}{{item.address}}text>
view>

<view class='item-edit'>
   <view class='left'>
        <radio value="{{index}}" checked="{{item.statu}}">
        <text class='ctr'>设为默认text>
        radio>
  view>
  <view class='right'>
      <text bindtap="navigateToEdit" data-id="1">编辑text> -
      <text bindtap="delAddr" data-id="1">删除text>
  view>
view>
view>
radio-group>

<navigator url="/pages/address/address">
<button style="position: fixed; bottom: 0; width: 100%; background-color: red; color: white; ">添加新地址button>
navigator>

js

  • addressList:用于存放所有收货地址

函数:

  • onshow()页面显示时执行,主要是进行获取收货地址并且进行赋值给addressList
  • radioChange():默认地址被修改时触发进行修改
// pages/addressList/addressList.js
Page({

    /**
     * 页面的初始数据
     */
    data: {
        addressList:[],
    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function () {
        let addressList=wx.getStorageSync('address')||[];
        if(addressList.length!=0){
            addressList[0].state=true;
        }
        this.setData({
            addressList:addressList
        })
    },
    /**默认地址被修改 */
    radioChange(e){
        let addr=this.data.addressList;
        for(let i=0;i<this.data.addressList.length;i++){
            addr[i].statu=false;
        }
        addr[e.detail.value].statu=true;
        wx.setStorageSync('address', addr)
    }
})

css样式

.list-item {
    font-size: 16px;
    padding: 30rpx;
    padding-bottom: 80rpx;
    margin-top: 20rpx;
    margin-bottom: 30rpx;
    background: pink;
  }
  .item-head {
    padding-bottom: 20rpx;
  }
  .item-desc {
    font-size: 16px;
  }
  .item-edit {
    margin-top: 20rpx;
    padding-top: 20rpx;
    border-top: 1px #ccc solid;
  }
  .right {
    padding-top: 10rpx;
    float: right;
    padding-right: 20rpx;
  }
  .left {
    float: left;
    vertical-align: middle;
  }
  .chk-active {
    color: #f31;
  }
  .ctr {
    position: relative;
    top: 6rpx;
  }

效果图展示

微信小程序商城项目实战(第九篇:收货地址管理)_第1张图片

新增收货地址

分析

需要用到一个js存储所有城市信息,需要的在评论区找我要~

  • 顶部改为新增收货地址
  • 中间则是需要填写的一些信息
  • 下方是一个保存按钮

代码实现

改变顶部导航内容"navigationBarTitleText": "新增收货地址"
界面:


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

js

  • 代码中写好了注释,直接看注释即可~

在此之前先写好一个存储城市信息的js
mock.js由于代码量过多,请在评论区向我要~

// pages/my/my-add-address/index.js
var address = require("../../utils/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)
    var label=this.data.labelList[this.data.labelDefault];
    console.log(label);
    if (consigneeName == "") {
      wx: wx.showToast({
        title: '请输入姓名',
        icon:'error'
      })
      return false
    }
    else if (phone == "") {
      wx: wx.showToast({
        title: '请输入手机号码',
        icon:'error'
      })
      return false
    }
    else if (consigneeRegion == "") {
      wx: wx.showToast({
        title: '请选择所在地区',
        icon:'error'
      })
      return false
    }
    else if (detailedAddress == "") {
      wx: wx.showToast({
        title: '请输入详细地址',
        icon:'error'
      })
      return false
    }
    else {
      var addr={
        name:consigneeName,
        tel:phone,
        city:consigneeRegion,
        address:detailedAddress,
        label:label,
        statu:false
      }
      var dizhi=wx.getStorageSync('address')||[];
      dizhi.push(addr);
      wx.setStorageSync('address', dizhi);
      wx.showToast({
        title: '添加成功',
        icon: 'success',
        duration: 1000//持续的时间
      })
      wx.navigateTo({
        url: '/pages/addressList/addressList',
      })
    }
  },
  /**
   * 生命周期函数--监听页面加载
   */
  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]
      })
    }
  },
 
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    var animation = wx.createAnimation({
      duration: 500,
      timingFunction: 'linear',
    })
    this.animation = animation
  },
})

css

/* 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;
  }

效果图

选择地区:
微信小程序商城项目实战(第九篇:收货地址管理)_第2张图片
并且会进行判断是否为空以及手机号验证!!!
这样一个完美的收货地址就完结了~

你可能感兴趣的:(微信小程序,微信小程序,前端)