微信小程序 ---- 慕尚花坊 收货地址

收货地址

  1. 收货地址列表
  2. 新增收货地址
  3. 编辑收货地址
  4. 删除收货地址

01. 定义新增参数以及封装接口 API

思路分析:

点击新建地址按钮,需要跳转到新增地址页面

因为新增和编辑收货地址页面是同一个页面,我们需要在这个页面处理新增和编辑功能,为了做区分处理。

我们在后续做进行编辑的时候传递 id 属性,值为 收货地址的 id 值。

首先熟悉接口文档:获取用户信息

接收文档在这一节,我们先来收集添加收货地址的请求参数

参数名称 参数说明 是否必须
收货人 name true
手机号 phone true
provinceName true
省 编码 provinceCode true
cityName true
市 编码 cityCode true
districtName true
区 编码 districtCode true
详细地址 fullAddress true
设置默认地址 isDefault (是否默认地址 → 0:否 1:是) false

实现步骤:

  1. 在新增收货地址页面 data 中声明所需要的字段
  2. 定义收货地址所需要的全部接口 API 函数

落地代码:

➡️ modules/settingModule/pages/address/add/index

js 复制代码
Page{{
  
  // 页面的初始数据
  data: {
	  name: '', // 收货人
      phone: '', // 手机号
      provinceName: '', // 省
      provinceCode: '', // 省 编码
      cityName: '', // 市
      cityCode: '', // 市 编码
      districtName: '', // 区
      districtCode: '', // 区 编码
      address: '',  // 详细地址
      fullAddress: '', // 完整地址 (省 + 市 + 区 + 详细地址)
      isDefault: 0 // 设置默认地址,是否默认地址 → 0:否  1:是
  }
}}

➡️ /api/address

js 复制代码
import http from '../utils/http'

/**
 * @description 实现新增收货地址
 * @param {*} data
 * @returns Promise
 */
export const reqAddAddress = (data) => {
  return http.post('/userAddress/save', data)
}

/**
 * @description 获取收货地址列表
 * @returns Promise
 */
export const reqAddressList = () => {
  return http.get('/userAddress/findUserAddress')
}

/**
 * @description 获取收货地址详情
 * @param {*} id 收货地址id
 * @returns Promise
 */
export const reqAddressInfo = (id) => {
  return http.get(`/userAddress/${id}`)
}

/**
 * @description 编辑收货地址
 * @param {*} data
 * @returns Promise
 */
export const reqUpdateAddress = (data) => {
  return http.post('/userAddress/update', data)
}

/**
 * @description 删除收货地址
 * @param {*} id 收货地址 id
 * @returns Promise
 */
export const reqDelAddress = (id) => {
  return instance.get(`/userAddress/delete/${id}`)
}

02. 收集省市区数据

思路分析

省市区的结构使用了小程序本身自带的picker 件,并将组件的 mode 属性设置为了 region,从而变成省市区选择器

如果想获取省市区的数据,需要给 picker 选择组件添加change 事件来监听属性值的改变,获取选中的省市区

html 复制代码
<!-- 省市县 -->
<view class="item">
  <text class="label">省/市/县 (区)</text>

  <!-- mode:给组件添加 mode 属性设置为了 region,从而变成省市区选择器 -->
  <!-- value:要求是一个数组,表示选中的省市区,默认选中每一列的第一个值 -->
  <!-- bindchange:来监听属性值的改变,也就是获取选中的省市区 -->
  <picker
    mode="region"
    value="{{ [provinceName, cityName, districtName] }}"
    bindchange="onAddressChange"
  >
    <view wx:if="{{ provinceName }}" class="region">
     {{ provinceName + ' ' + cityName + ' ' + districtName }}
    </view>
    <view wx:else class="placeholder">请填写收货人所在城市</view>
  </picker>

  <view class="location" bindtap="onLocation">
    <van-icon name="location-o" color="#777" />
    <text>定位</text>
  </view>
</view>

实现步骤

  1. picker 选择组件添加change 事件来监听属性值的改变,获取选中的省市区
  2. 将获取到省市区标识和编码赋值给 data中的字段

落地代码

➡️ modules/settingModule/pages/address/add/index

js 复制代码
Page({
   
  // coding...
    
  // 省市区选择
  onAddressChange(event) {
    const [provinceCode, cityCode, districtCode] = event.detail.code
    const [provinceName, cityName, districtName] = event.detail.value

    // 存储省市区对应的编码
    this.setData({
      provinceCode,
      provinceName,
      cityCode,
      cityName,
      districtName,
      districtCode
    })
  }
    
  // coding...
})

03. 收集新增地址其他请求参数

思路分析:

使用简易双向数据 model:value 绑定来收集新增地址表单数据。

在将数据收集以后,需要组织两个数据:

  1. 是否是默认地址,0 不设置为默认地址,1 设置为默认地址
  2. 拼接完整的收货地址

实现步骤:

  1. 使用简易双向数据绑定来收集新增地址表单数据。
  2. 给按钮绑定点击事件,在事件处理函数中收集并整理数据

落地代码:

js 复制代码
Page({
    
  // coding...
    
  // 获取表单元素的值
  saveAddrssForm(event) {
      
    // 解构出省市区以及 是否是默认地址
    const { provinceName, cityName, districtName, address, isDefault } = this.data
    
    // 拼接完整的地址
    const fullAddress = provinceName + cityName + districtName + address
      
    // 合并接口请求参数
    const params = {
      ...this.data,
      fullAddress,
      isDefault: isDefault ? 1 : 0
    }


    console.log(params)
  }
})

04. 地理定位功能介绍

地理定位介绍:

小程序地理定位是指通过小程序开发平台提供的 API,来获取用户的地理位置信息。用户在使用小程序时,可以授权小程序获取自己的地理位置信息

  1. wx.getLocation() :获取当前的地理位置
  2. wx.chooseLocation():打开地图选择位置

申请开通:

暂时只对部分类目的小程序开放,需要先通过类目审核,然后在小程序管理后台,「开发」-「开发管理」-「接口设置」中自助开通该接口权限。

使用方法:

  1. 在 app.json 中配置 requiredPrivateInfos 进行声明启用

  2. 在调用 wx.getLocation() 时需要在 app.json 配置 permission 字段,同时使用 scope.userLocation 声明收集用户选择的位置信息 的目的,wx.chooseLocation() 接口不需要配置该字段,可以直接进行调用

  3. 在配置好以后,调用 wx.getLocation()wx.chooseLocation() 接口

参考文档:

  1. 地理位置接口新增与相关流程调整
  2. permission 字段说明

app.json 中进行配置

json 复制代码
{
  "requiredPrivateInfos": [
    "getLocation",
    "chooseLocation"
  ],
  "permission": {
    "scope.userLocation": {
      "desc": "获取用户位置信息用于填写收货地址"
    }
  }
}

getLocation 使用:

js 复制代码
// 地理定位
async onLocation() {
  // 获取 纬度 、精度
  const { latitude, longitude } = await wx.getLocation()
  console.log(location)
}

chooseLocation 使用:

js 复制代码
// 地理定位
async onLocation() {
  // 打开地图选择位置,获取 纬度 、精度
  const { latitude, longitude }  = await wx.chooseLocation()
  console.log(res)
}

05. 拒绝授权后的解决方案

在调用 wx.getLocation() 获取用地理位置时,如果用户选择拒绝授权,代码会直接抛出错误。

在拒绝授权以后,再次调用 wx.getLocation() 时,就不会在弹窗询问用户是否允许授权。

接下来,就需要优化授权的流程:

  1. wx.getSetting():获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限
  2. wx.openSetting(): 调起客户端小程序设置界面,返回用户设置的操作结果

📌 注意事项:

  1. 如果希望用户再次授权,就需要让用户进行 手动开启授权
  2. wx.openSetting() 必须用户发生点击行为后,才可以跳转到设置页进行授权信息管理。
js 复制代码
// 获取用户地理位置信息
async onLocation() {
  // 调用 getSetting 方法获取用户所有的授权信息
  // 返回的 authSetting 包含小程序已向小程序申请过的权限已经授权结果(true、false)
  const { authSetting } = await wx.getSetting()
  console.log(authSetting)

  // scope.userLocation 是否已经授权获取地理位置的信息
  // 如果之前没有申请过返回 undefined,需要调用 getLocation
  // 如果之前同意了授权,返回 true,需要调用 getLocation
  // 如果之前拒绝了授权,返回 false,需要用户手动进行授权
  // 等于 true,或者不等于 undefined,说明需要进行授权
  // const isAuth =
  //   authSetting['scope.userLocation'] ||
  //   authSetting['scope.userLocation'] === undefined

  // 为了避免冗余的条件判断,使用 !! 把代码进行优化
  const isAuth = !!authSetting['scope.userLocation']

  if (!isAuth) {
    // 弹窗询问用户是否进行授权
    const modalRes = await wx.modal({
      title: '授权提示',
      content: '需要需要您的地理位置信息,请确认授权'
    })

    // 如果用户点击了取消,说明用户拒绝了授权,给用户提示
    if (!modalRes) return wx.toast({ title: '您拒绝了授权' })

    // 如果用户点击了确定,调用 wx.openSetting 打开微信客户端小程序授权页面
    // 并返回授权以后的结果
    const { authSetting } = await wx.openSetting()

    // 如果用户没有更新授权信息,提示没有更新授权
    if (!authSetting['scope.userLocation'])
      return wx.toast({ title: '授权失败!' })

    try {
      // 如果用户更新授权信息,则调用 getLocation 获取用户地理位置信息
      const locationRes = await wx.getLocation()
      // 打印地理位置信息
      console.log(locationRes)
    } catch (err) {
      console.log(err)
    }
  } else {
    try {
      // 如果是第一次调用 getLocation 或者之前授权过
      // 直接调用 getLocation 获取用户信息即可
      const locationRes = await wx.getLocation()
      console.log(locationRes)
    } catch (error) {
      wx.toast({ title: '您拒绝授权获取地址位置' })
    }
  }
}

06. 开通腾讯位置服务

腾讯位置服务简介:

使用wx.chooseLocation()能够很方便的让用户来选择地理位置,但是wx.chooseLocation()返回的数据并没有包含省市区、省市区编码数据。而新增收货地址接口,需要传递省市区、省市区编码数据。

这时候我们可以使用 腾讯位置服务 将返回的经度、纬度进行逆地址解析,转换成详细地址。

腾讯位置服务专为小程序开发提供了 JavaScript SDK,方便开发者在小程序中可以使用腾讯地图服务。

使用腾讯位置服务可以很方便的让开发者实现地址解析、逆地址解析等功能。

使用步骤:

  1. 申请开发者密钥(key):申请密钥
  2. 开通 webserviceAPI 服务:控制台 → 应用管理→我的应用 → 添加 key →勾选 WebServiceAPI →保存
  3. 下载微信小程序 JavaScriptSDK,微信小程序JavaScriptSDK v1.1 JavaScriptSDK v1.2
  4. 安全域名设置

详细步骤:

  1. 申请密钥:密钥申请,微信扫码进行登录,选择绑定已有账号、或者注册新账号 (需要绑定手机、验证邮箱)

  2. 控制台 → 应用管理→我的应用 → 创建应用 → 添加 key → 创建完成

  1. 下载微信小程序 JavaScriptSDK v1.2,下载将 .js 文件放到小程序的 libs 目录下

  2. 进行安全域名设置,或者点击微信开发者工具中的暂时不校验域名

07. LBS 逆地址解析

使用步骤:

  1. 在项目中引入 SDK 核心类
  2. onLoad 中实例化 API 核心类,同时配置创建的 key
  3. 使用实例方法 reverseGeocoder 方法进行逆地址解析,将提供的坐标转换为详细的地址位置信息

官方文档-基础示例:Hello World

官方文档-逆地址解析:reverseGeocoder

落地代码:

  1. 引入 SDK 核心类

    js 复制代码
    // var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');
    import QQMapWX from '../../../../../libs/qqmap-wx-jssdk.min'
  2. 实例化 API 核心类

    js 复制代码
    // 引入SDK核心类,js文件根据自己业务,位置可自行放置
    import QQMapWX from '../../../../../libs/qqmap-wx-jssdk.min'
    
    Page({
     
      onLoad: function () {
    
        // 实例化API核心类
        this.qqmapsdk = new QQMapWX({
          key: '申请的key'
        })
     
      }
        
      // coding...   
    }
  3. 使用 reverseGeocoder 方法进行逆地址解析,将提供的坐标转换为所在位置的文字描述的转换

    js 复制代码
    // LBS 地址逆解析
    // 地理定位
    async onLocation() {
      // 获取 纬度 、精度
      // const { latitude, longitude } = await wx.getLocation()
      // console.log(location)
    
      // 获取经、纬度、位置名称
      let { latitude, longitude, name } = await wx.chooseLocation()
    
      // 使用 reverseGeocoder 方法进行逆地址解析
      this.qqmapsdk.reverseGeocoder({
        // 传入经、纬度
        location: {
          latitude,
          longitude
        },
    
        // 逆地址解析成功后执行
        success: (res) => {
          // 获取选择的
          const { street_number } = res.result.address_component
    
          // province 省  city 市  district 区
          const {
            province, // 省
            city, // 市
            district, // 区
            adcode, // 行政区划代码
            city_code, // 城市代码,由国家码+行政区划代码(提出城市级别)组合而来,总共为9位
            nation_code // 国家代码
          } = res.result.ad_info
    
          this.setData({
            // 省级: 前两位有值,后4位置0,如,河北省: 130000
            provinceCode: adcode.replace(adcode.substring(2, 6), '0000'),
            provinceName: province,
    
            // 市前面多个国家代码,需要进行截取
            cityCode: city_code.slice(nation_code.length),
            cityName: city,
    
            // 东莞市、中山市、修州市、嘉关市 因其下无区县级,
            districtCode: district && adcode,
            districtName: district,
    
            // 详细地址
            address: name,
            fullAddress: [province, city, district, address].join('')
          })
        }
      })
    }

09. 新增收货地址表单验证

思路分析:

在点击新增收货地址的时候,我们需要对用户输入的值进行验证。产品需求如下:

  1. 收货人不能为空,且不能输入特殊字符
  2. 手机号不能为空,且输入的手机号必须合法
  3. 省市区不能为空
  4. 详细地址不能为空

正则:

js 复制代码
// 验证收货人,是否只包含大小写字母、数字和中文字符
const nameRegExp = '^[a-zA-Z\\d\\u4e00-\\u9fa5]+$'

// 验证手机号,是否符合中国大陆手机号码的格式
const phoneReg = '^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$'

实现步骤:

  1. 创建 validateForm 方法,使用 async-validator 对表单进行验证
  2. 在新增收货地址之前,调用 validateForm 方法,如果验证成功执行新增守护地址的逻辑

落地代码:

➡️ /modules/settingModule/pages/address/add/index

js 复制代码
import Schema from 'async-validator'

Page({

  // coding....

    // 保存收货地址
  async saveAddrssForm() {
    // 组织参数 (完整地址、是否设置为默认地址)

    const {
      provinceName,
      cityName,
      districtName,
      address,
      isDefault
    } = this.data

    // 最终需要发送的请求参数
    const params = {
      ...this.data,
      fullAddress: provinceName + cityName + districtName + address,
      isDefault: isDefault ? 1 : 0
    }

    // 调用方法对最终的请求参数进行验证
    const { valid } = await this.validateAddress(params)

    // 如果验证没有通过,不继续执行后续的逻辑
    if (!valid) return
    
    console.log(params)
  },

  // 验证新增收货地址请求参数
  // 形参 params 是需要验证的数据
  validateAddress(params) {
    // 验证收货人,是否只包含大小写字母、数字和中文字符
    const nameRegExp = '^[a-zA-Z\\d\\u4e00-\\u9fa5]+$'

    // 验证手机号
    const phoneReg = '^1(?:3\\d|4[4-9]|5[0-35-9]|6[67]|7[0-8]|8\\d|9\\d)\\d{8}$'

    // 创建验证规则,验证规则是一个对象
    // 每一项是一个验证规则,验证规则属性需要和验证的数据进行同名
    const rules = {
      name: [
        { required: true, message: '请输入收货人姓名' },
        { pattern: nameRegExp, message: '收货人姓名不合法' }
      ],
      phone: [
        { required: true, message: '请输入收货人手机号' },
        { pattern: phoneReg, message: '手机号不合法' }
      ],
      provinceName: { required: true, message: '请选择收货人所在地区' },
      address: { required: true, message: '请输入详细地址' }
    }

    // 创建验证实例,并传入验证规则
    const validator = new Schema(rules)

    // 调用实例方法对数据进行验证
    // 注意:我们希望将验证结果通过 Promsie 的形式返回给函数的调用者
    return new Promise((resolve) => {
      validator.validate(params, (errors, fields) => {
        if (errors) {
          // 如果验证失败,需要给用户进行提示
          wx.toast({
            title: errors[0].message
          })

          resolve({ valid: false })
        } else {
          resolve({ valid: true })
        }
      })
    })
  },


  // coding...
})

10. 实现新增收货地址

思路分析:

在实现了新增收货地址的数据收集、表单验证以后,我们需要实现新增收货地址的功能,将用户的收货地址到服务器。我们直接根据接口文档,封装接口 API,然后在表单验证以后,进行收货地址的添加即可。

实现步骤:

  1. 在对新增收货地址请求参数验证以后,将封装好的新增收货地址的 API 函数调用

  2. 在新增收货地址成功以后,跳转到收货地址详情页面。

落地代码:

➡️ /pages/address/add/index.js

js 复制代码
// 新增或修改地址
async saveAddrssForm(event) {
  // 组织参数 (完整地址、是否设置为默认地址)
  const {
    provinceName,
    cityName,
    districtName,
    address,
    isDefault
  } = this.data

  // 最终需要发送的请求参数
  const params = {
    ...this.data,
    fullAddress: provinceName + cityName + districtName + address,
    isDefault: isDefault ? 1 : 0
  }
  
  // 如果验证没有通过,不进行后续处理
  if (!valid) return

  // 发送请求,保存收货地址
  const res = await reqAddAddress(params)
  
  if (res.code === 200) {
    wx.navigateBack({
      success() {
        wx.toast({ title: '新增收货地址成功' })
      }
    })
  }
    
}

11. 收货地址列表渲染

思路分析:

渲染收货地址需要收货地址的数据,需要调用接口获取收货地址数据,使用返回的数据进行结构的渲染。

先熟悉接口文档:获取收货地址

在熟悉了接口文档以后,根据接口文档封装接口 API 函数,然后在页面调用 API 函数获取收货地址的数据,在获取到数据以后,使用后端返回的数据对页面进行渲染。

实现步骤:

  1. onShow 钩子函数中调用reqAddressList方法

  2. 在获取到数据以后,使用后端返回的数据对页面进行渲染

落地代码:

➡️ /modules/settingModule/pages/address/list/index.js

js 复制代码
// pages/address/list/index.js
+ import { reqAddressList } from '../../../../../api/address'

Page({
  // 页面的初始数据
  data: {
+     addressList: [] // 收货地址列表
  },

+   // 获取收货地址
+   async getAddressList() {
+     // 调用 API,获取收货地址
+     const { data: addressList } = await reqAddressList()
+ 
+     this.setData({
+       addressList
+     })
+   },

  // 去编辑页面
  toEdit() {
    wx.navigateTo({
      url: '/modules/settingModule/pages/address/add/index'
    })
  },

+   onLoad() {
+     this.getAddressList()
+   }
})

➡️ /modules/settingModule/pages/address/list/index.wxml

html 复制代码
<view class="list-warpper" wx:if="{{ addressList.length }}">
  <view wx:for="{{ addressList }}" wx:key="id" class="list-item">
    <van-swipe-cell right-width="{{ 65 }}">
      <view class="list-item-box">
        <view class="info">
          <view class="user-info">
+             <text>{{ item.name }}</text>
+             <text>{{ item.phone }}</text>
+             <text wx:if="{{ item.isDefault }}" class="default-tag">默认</text>
          </view>

+           <view class="address-info"> {{ item.fullAddress }} </view>
        </view>

        <view class="editBtn">
          <van-icon bindtap="toEdit" name="edit" size="22px" color="#999" />
        </view>
      </view>
      <!-- <van-icon name="delete" size="22px" color="#999" /> -->
      <view slot="right" class="van-swipe-cell__right">
        <text>删除</text>
      </view>
    </van-swipe-cell>
  </view>
</view>

12. 实现更新收货地址

思路分析:

新增和编辑收货地址页面是同一个页面,我们需要在这个页面处理新增和编辑功能

在收货地址列表页面,点击更新按钮时,需要跳转到新增/更新页面,同时需要将更新这一项的 id 传递给新增/更新页面。

onLoad 中获取 id,并且使用 id 区分用户是进行新增还是编辑的操作。

如果存在 id,在获取需要更新的收货地址的数据,并进行页面的回显用户的收货地址,并且需要更新导航栏标题

因为我们之前直接是将数据放到 data 中的,所以我们直接将数据使用 setData 赋值即可

首先熟悉接口文档:获取收货地址详情

实现步骤:

  1. 在从收货地址列表页面跳转到更新页面的时候,需要携带 id
  2. onLoad 中判断是否存在 id,如果存在 id,在获取数据进行回显

落地代码:

➡️ /modules/settingModule/pages/address/list/index.wxml

html 复制代码
<!-- 编辑、删除按钮 -->
<van-icon bindtap="toEdit" data-id="{{ item.id }}" name="edit" size="22px" color="#999" />

➡️ /modules/settingModule/pages/address/list/index.js

js 复制代码
// 去编辑页面
toEdit(event) {
  // 需要编辑的收货地址
  const { id } = event.target.dataset

  wx.navigateTo({
    url: `/modules/settingModule/pages/address/add/index?id=${id}`
  })
}

➡️ /modules/settingModule/pages/address/add/index.js

js 复制代码
Page({
   
  // coding...
    
  // 保存收货地址
  async saveAddrssForm() {
    // 组织参数 (完整地址、是否设置为默认地址)
    const {
      provinceName,
      cityName,
      districtName,
      address,
      isDefault
    } = this.data

    // 最终需要发送的请求参数
    const params = {
      ...this.data,
      fullAddress: provinceName + cityName + districtName + address,
      isDefault: isDefault ? 1 : 0
    }

    // 调用方法对最终的请求参数进行验证
    const { valid } = await this.validateAddress(params)

    // 如果验证没有通过,不继续执行后续的逻辑
    if (!valid) return

+     // 发送请求,保存收货地址
+     const res = this.addressId
+       ? await reqUpdateAddress(params)
+       : await reqAddAddress(params)

+     if (res.code === 200) {
+       // 提示用户更新状态
+       wx.toast({
+         title: this.addressId ? '编辑收货地址成功' : '新增收货地址成功'
+       })
+ 
+       // 返回到收货地址列表页面
+       wx.navigateBack()
    }
  },
   
+   // 回显收货地址的逻辑
+   showAddressInfo(id) {
+     // 判断是否存在 id,如果不存在 id,return 不执行后续的逻辑
+     if (!id) return
+ 
+     // 如果存在 id,将 id 挂载到 this 页面实例上
+     this.addressId = id
+ 
+     // 动态设置当前页面的标题
+     wx.setNavigationBarTitle({
+       title: '更新收货地址'
+     })
+ 
+     // 调用方法获取收货地址详细信息
+     const { data } = await reqAddressInfo(this.addressId)
+     // 将获取的数据进行赋值
+     this.setData(data)
+   },

  onLoad(options) {
    // 对核心类 QQMapWX 进行实例化
    this.qqmapwx = new QQMapWX({
      // key 要使用自己申请的 key
      // 在进行逆解析的时候,如果发现 key 只能使用一次,需要在腾讯位置服务后台配置额度
      key: 'S5CBZ-TQXCB-L73UJ-J6VJA-FXS53-JNBY3'
    })

+     // 回显收货地址的逻辑
+     this.showAddressInfo(options.id)
  }
    
  // coding...
})

13. 实现删除收货地址

思路分析:

点击删除按钮的时候,需要将对应的地址进行删除

当点击删除按钮的时候,调用封装的接口 API 函数 ,同时传递需要删除的收货地址 id 即可

实现步骤:

  1. 给删除按钮绑定点击事件 delAddress,同时通过 data-id 传递需要删除的商品 id
  2. delAddress 事件处理程序后面,调用 API 函数 reqDelAddress,并传递 id
  3. 在删除收货地址成功以后,给用户提示

落地代码:

➡️ /modules/settingModule/pages/address/list/index.wxml

js 复制代码
<van-icon
+   bindtap="delAddress"
+   data-id="{{ item.id }}" 
  name="delete"
  size="22px"
  color="#999"
/>

➡️ /modules/settingModule/pages/address/list/index.js

js 复制代码
// 删除收货地址
async delAddress(e) {
  const { id } = e.target.dataset

  await reqDelAddress(id)
  this.getAddressList()
}

优化:SwipeCell 自动收起删除滑块

目前我们已经实现了滑块删除收货地址的功能,

但是我们会发现点击页面空白区域或者点击其他收货地址时,删除的滑块不会自动收起。

如果想实现点击空白区域自动收起滑块功能,需要在 点击空白区域 以及 其他收货地址时,获取要收起的滑块实例。

调用对应滑块的实例方法 close 即可。

实现思路:

  1. 给滑块绑定 id
  2. 在打开滑块时,获取当前滑块的实例,然后将实例存储到 data 的数组中。
  3. 给页面最外层的 view 同时给滑块区域绑定点击事件,在事件处理函数中对数据遍历,每一项调用 close 方法关掉滑块
  4. 将关掉的逻辑抽取成 behavior 文件,方便在其他文件中进行复用。

落地代码:

➡️ /behavior/swipeCellBahavior.js

js 复制代码
export const swipeCellBehavior = Behavior({
  data: {
    swipeCelQueue: [] // 实例存储队列
  },

  methods: {
    // 打开滑块时,将实例存储到队列中
    onSwipeCellOpen(event) {
      let instance = this.selectComponent(`#${event.target.id}`)
      this.data.swipeCelQueue.push(instance)
    },

    // 点击其他滑块时,关掉开启的滑块
    onSwipeCellClick() {
      this.onSwipeCellCommonClick()
    },

    // 点击页面空白区域时,关掉开启的滑块
    onSwipeCellPageTap() {
      this.onSwipeCellCommonClick()
    },

    // 关掉滑块的统一方法
    onSwipeCellCommonClick() {
      // 循环关闭开启的滑块
      this.data.swipeCelQueue.forEach(function (instance) {
        instance.close()
      })
        
      // 将滑块进行清空
      this.data.swipeCelQueue = []
    }
  }
})

➡️ /modules/settingModule/pages/address/list/index.wxml

html 复制代码
<view class="container address-list" bindtap="onSwipeCellPageTap">

  <van-swipe-cell
    right-width="{{ 65 }}"
+     data-id="{{ item.id }}"
+     bind:open="onSwipeCellOpen"
+     bind:click="onSwipeCellClick"
  >
  
    <!-- 代码略... -->
  
  </van-swipe-cell>

</view>
相关推荐
郭wes代码5 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
.生产的驴10 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
汤姆yu15 小时前
基于微信小程序的乡村旅游系统
微信小程序·旅游·乡村旅游
计算机徐师兄16 小时前
基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
小程序·php·家具购物小程序·家具购物微信小程序·家具购物
曲辒净16 小时前
微信小程序实现二维码海报保存分享功能
微信小程序·小程序
朽木成才18 小时前
小程序快速实现大模型聊天机器人
小程序·机器人
peachSoda718 小时前
随手记:小程序使用uni.createVideoContext视频无法触发播放
小程序
何极光18 小时前
uniapp小程序样式穿透
前端·小程序·uni-app
小墨&晓末19 小时前
【PythonGui实战】自动摇号小程序
python·算法·小程序·系统安全
oil欧哟1 天前
🤔认真投入一个月做的小程序,能做成什么样子?有人用吗?
前端·vue.js·微信小程序