小程序地址管理/ 修改/ 左滑删除

2021-01-26  本文已影响0人  w_小伍

完整小程序地址:https://github.com/aipdx/webChat-app-demo

功能有:地址列表,新增,修改,左滑删除地址


image.png

效果图
地址列表


image.png
新增地址
image.png

编辑地址


image.png
左滑删除
image.png

在app.json里引入weui

"useExtendedLib": {
    "weui": true
  },

在使用左滑功能的页面json里引入组件

"usingComponents": {
    "mp-slideview": "weui-miniprogram/slideview/slideview"
  },

地址列表代码:

<view class="addr_wrap">
  <!--没有地址-->
  <view wx:if="{{!address.length}}" class="no_addr_wrap">
    <navigator url="/pages/address_manage/address_manage" hover-class="none">新增地址</navigator>
  </view>
  <!--有地址-->
  <view wx:else class="have_addr_wrap">
    <view wx:for="{{address}}" wx:key="index" class="slideview_wrap">
      <mp-slideview buttons="{{slideButtons}}" data-index="{{index}}" bindbuttontap="slideButtonTap">
        <view class="addr_item">
          <view class="checkbox_wrap">
            <radio-group bindchange="handleAddress" data-index="{{index}}">
              <radio checked="{{item.checked}}" value="{{item.userName}}" color="#eb4450"></radio>
            </radio-group>
          </view>
          <view class="addr_detail">
            <view class="addr_name">
              <text class="name_txt">{{item.userName}}</text>
              <text class="tel_txt">{{item.telNumber}}</text>
            </view>
            <view class="addr_txt_wrap">
              <view class="addr_txt">地址:</view>
              <view class="detail_txt">{{item.all}}</view>
            </view>
          </view>
          <navigator
            url="/pages/address_manage/address_manage?id={{index}}"
            hover-class="none"
            class="edit_wrap icon-xiugai iconfont">
          </navigator>
        </view>
      </mp-slideview>
    </view>
  </view>
</view>
<view class="add_addr_tool">
  <navigator url="/pages/address_manage/address_manage" hover-class="none" class="tool_wrap">
    <view class="add_icon">+</view>
    <view class="add_txt">新增个人地址</view>
    <view class="jiantou_icon">></view>
  </navigator>
</view>

Page({
  data: {
    address: [], // 所有地址数组
    slideButtons: [{ // 左滑按钮配置
      type: 'warn',
      text: '删除'
    }],
  },
  onShow() {
    this.getAddress()
  },
  // 获取地址信息
  getAddress() {
    const addressList = wx.getStorageSync('addressList') || [] // 用户自己在新增地址页面添加的
    addressList.map(v => {
      if (!v.checked) { // 如果没有checked就添加一个
        v.checked = false
      }
    }) // 给地址添加一个是否选中的标识
    this.setData({address: addressList})
  },
  // 选择地址
  handleAddress(e) {
    const {index} = e.currentTarget.dataset
    let {address} = this.data
    address.forEach((v, i) => i === index ? v.checked = true : v.checked = false)
    this.setData({
      address
    })
    wx.setStorageSync('addressList', address)
  },
  slideButtonTap(e) {
    const {index} = e.detail // index对应的是slideButtons数组的索引 index为多少就表示点击的是数组的第几个
    const currentIndex = e.currentTarget.dataset.index // 点击当前的索引
    let {address} = this.data
    if (index === 0) { // 删除
      wx.showModal({
        content: '确认删除吗',
        success: (res) => {
          if (res.confirm) { // 用户点击了确定
            address.splice(currentIndex, 1) // 删除当前索引对应的数据
            this.setData({address})
            wx.setStorageSync('addressList', address)
          } else {
            console.log('用户点击了取消')
          }
        }
      })
    }
  }
})

css

page {
  background-color: #dddddd;
  height: 100vh;
  padding-bottom: 90rpx;
}

.no_addr_wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  padding-top: 20rpx;

  navigator {
    color: #06ae56;
    font-size: 40rpx;
    width: 70%;
    border-radius: 15rpx;
    height: 90rpx;
    border: 1px solid #06ae56;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
  }
}

.have_addr_wrap {
  padding: 20rpx;

  .slideview_wrap {
    margin-top: 15rpx;

    &:first-child {
      margin-top: 0;
    }

    /deep/ .weui-slideview__btn {
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }

  .addr_item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background-color: #fff;
    padding: 30rpx 10rpx;
  }

  .checkbox_wrap {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;

    radio {
      transform: scale(0.7);
    }
  }

  .addr_detail {
    flex: 8;
    margin-left: 15rpx;

    .addr_name {
      color: #666666;
    }

    .tel_txt {
      margin-left: 20rpx;
    }

    .addr_txt_wrap {
      color: #666666;
      margin-top: 15rpx;
      display: flex;

      .addr_txt {
        flex-shrink: 0;
      }
    }
  }

  .edit_wrap {
    flex: 1;
    color: #666666;
    font-size: 30rpx;
    display: flex;
    justify-content: center;
  }
}

.add_addr_tool {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  background-color: #fff;
  height: 90rpx;
  padding: 0 20rpx;

  .tool_wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 100%;

    .add_icon {
      width: 30rpx;
      height: 30rpx;
      border-radius: 50%;
      line-height: 29rpx;
      text-align: center;
      background-color: var(--themeColor);
      color: #ffffff;
    }

    .add_txt {
      flex: 30;
      margin-left: 15rpx;
      color: #666666;
    }

    .jiantou_icon {
      flex: 1;
      color: #acacac;
      font-size: 36rpx;
    }
  }
}

编辑地址页面address_manage

<form bindsubmit="submitForm">
  <view class="addr_manage">
    <view class="addr_ma_item">
      <view class="addr_ma_txt">姓名</view>
      <view class="addr_ma_input">
        <input placeholder="请填写收货人姓名" value="{{form.userName}}" name="userName" placeholder-class="placeholder_class"/>
      </view>
    </view>
    <view class="addr_ma_item">
      <view class="addr_ma_txt">电话</view>
      <view class="addr_ma_input">
        <input placeholder="请填写收货电话" value="{{form.telNumber}}" name="telNumber" placeholder-class="placeholder_class"/>
      </view>
    </view>
    <view class="addr_ma_item province_select">
      <view class="picker_wrap">
        <view class="addr_ma_txt">省市区</view>
        <picker mode="region" bindchange="bindRegionChange" value="{{form.region}}" name="region" custom-item="{{customItem}}">
          <view class="{{form.region[1]?'':'default_picker'}}">
            {{form.region[0]}}
            {{form.region[1]?'-':''}}
            {{form.region[1]}}
            {{form.region[1]?'-':''}}
            {{form.region[2]}}
          </view>
        </picker>
      </view>
      <view class="addr_ma_icon">></view>
    </view>
    <view class="addr_ma_item">
      <view class="addr_ma_txt">详细信息</view>
      <view class="addr_ma_input">
        <input placeholder="街道、楼牌号等" value="{{form.addrDetail}}" name="addrDetail" placeholder-class="placeholder_class"/>
      </view>
    </view>
  </view>
  <!--提交按钮-->
  <view class="submit_btn_wrap">
    <button type="primary" formType="submit">提交</button>
    <button type="warn" bindtap="restForm" plain>取消</button>
  </view>
</form>
const app = getApp()
Page({
  data: {
    form: {
      userName: '',
      telNumber: '',
      addrDetail: '',
      region: ['请选择省市区/县', '', ''], // 省市区数据 第一个可以当placeholder
    },
    customItem: '', // 自定义picker显示的内容
  },
  Postcode: '', // 邮编
  AddressId: -1,
  onShow() {
    const {id} = app.getPage(1).options
    if (id >= 0) {
      this.AddressId = id
      this.getEditAddress(id)
    }
  },
  // 省市区选择事件
  bindRegionChange(e) {
    const {value, code, postcode} = e.detail
    // console.log(code) // 统计用区划代码
    // postcode 是邮政编码
    this.Postcode = postcode
    this.setData({
      'form.region': value
    })
  },
  // 提交表单
  submitForm(e) {
    if (!this.validateForm(e)) return
    // userName,telNumber...对应的是input的name属性
    const {userName, telNumber, region, addrDetail} = e.detail.value
    const addressList = wx.getStorageSync('addressList') || []
    if (this.AddressId >= 0) { // 编辑地址
      addressList[this.AddressId].userName = userName
      addressList[this.AddressId].telNumber = telNumber
      addressList[this.AddressId].postalCode = this.Postcode
      addressList[this.AddressId].provinceName = region[0]
      addressList[this.AddressId].cityName = region[1]
      addressList[this.AddressId].countyName = region[2]
      addressList[this.AddressId].detailInfo = addrDetail
      addressList[this.AddressId].all = region[0] + region[1] + region[2] + addrDetail
    } else { // 新增地址
      const address = {
        userName,
        telNumber,
        postalCode: this.Postcode,
        provinceName: region[0],
        cityName: region[1],
        countyName: region[2],
        detailInfo: addrDetail,
        all: region[0] + region[1] + region[2] + addrDetail
      }
      addressList.push(address)
    }
    wx.setStorageSync('addressList', addressList)
    wx.showToast({
      title: '提交成功',
    })
    wx.navigateBack({
      delta: 1
    })
  },
  // 验证form
  validateForm(e) {
    const telReg = app.regExps.mobile
    const {userName, telNumber, region, addrDetail} = e.detail.value
    if (!userName.trim()) {
      wx.showToast({
        title: '请先填写姓名',
        icon: "none"
      })
      return false
    }
    if (!telNumber.trim() || !telReg.test(telNumber)) {
      wx.showToast({
        title: '请先填正确的手机号',
        icon: "none"
      })
      return false
    }
    if (!region.length) {
      wx.showToast({
        title: '请先选择省市区',
        icon: "none"
      })
      return false
    }
    if (!addrDetail.trim()) {
      wx.showToast({
        title: '请先填写详细信息',
        icon: "none"
      })
      return false
    }
    return true
  },
  // 编辑地址获取需要编辑的地址信息
  getEditAddress(id) {
    const addressList = wx.getStorageSync('addressList') || []
    const address = addressList[id]
    this.setData({
      'form.userName': address.userName,
      'form.telNumber': address.telNumber,
      'form.addrDetail': address.detailInfo,
      'form.region': [address.provinceName, address.cityName, address.countyName],
    })
  },
  // 重置表单
  restForm() {
    this.setData({
      'form.userName': '',
      'form.telNumber': '',
      'form.addrDetail': '',
      'form.region': []
    })
    wx.navigateBack({
      delta: 1
    })
  }
})
page {
  background-color: #f9f9f9;
}

.addr_manage {
  .addr_ma_item {
    display: flex;
    border-bottom: 1px solid #ececec;
    padding: 20rpx;
    align-items: center;
    color: #666666;

    .addr_ma_txt {
      display: 2;
    }

    .addr_ma_input {
      flex: 4;
      margin-left: 30rpx;
      padding-right: 20rpx;
    }
  }

  .province_select {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .picker_wrap {
      display: flex;
      flex: 5;

      .addr_ma_txt {
        margin-right: 20rpx;
      }

      picker {
        width: 70%;
      }
      .default_picker {
        color: #acacac;
      }
    }

    .addr_ma_icon {
      font-size: 30rpx;
      color: #acacac;
    }
  }
}

.submit_btn_wrap {
  margin-top: 20rpx;
  padding: 0 20rpx;
  width: 100%;

  button {
    font-weight: normal;
    width: 100% !important;
    margin-top: 20rpx;
  }
}

app.js

// app.js
App({
  onLaunch() {
    // 将是否iphoneX 信息缓存到全局公众数据中
    this.globalData.isIphoneX = this.isIphoneX()
  },
  // iphoneX兼容 有刘海屏
  isIphoneX() {
    let mobile = wx.getSystemInfoSync()
    if (mobile.model.indexOf("iPhone X") >= 0) {
      return true
    } else {
      return false
    }
  },
  // 常用正则表达式集
  regExps: {
    email: /^[0-9a-zA-Z_]+@[0-9a-zA-Z_]+[\.]{1}[0-9a-zA-Z]+[\.]?[0-9a-zA-Z]+$/, //邮箱
    mobile: /^(?:1\d{2})-?\d{5}(\d{3}|\*{3})$/, //手机号码
    qq: /^[1-9][0-9]{4,9}$/, //QQ
    befitName: /^[a-z0-9A-Z\u4e00-\u9fa5]+$/, //合适的用户名,中文,字母,数字
    befitPwd: /^[a-z0-9A-Z_]+$/, //合适的用户名,字母,数字,下划线
    allNumber: /^[0-9]+.?[0-9]$/ //全部为数字
  },
  // 获取上一页路由
  getPage(index) {
    const pages = getCurrentPages()
    const prevPage = pages[pages.length - index]
    return prevPage
  },
  globalData: {
    isIphoneX: false
  },
})

上一篇下一篇

猜你喜欢

热点阅读