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

完整小程序地址: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
  },
})

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容