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

news/发布时间2024/9/20 5:46:31

收货地址

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

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

思路分析:

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

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

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

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

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

参数名称参数说明是否必须
收货人nametrue
手机号phonetrue
provinceNametrue
省 编码provinceCodetrue
cityNametrue
市 编码cityCodetrue
districtNametrue
区 编码districtCodetrue
详细地址fullAddresstrue
设置默认地址isDefault (是否默认地址 → 0:否 1:是)false

实现步骤:

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

落地代码:

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

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

➡️ /api/address

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 事件来监听属性值的改变,获取选中的省市区

<!-- 省市县 -->
<view class="item"><text class="label">省/市/县 (区)</text><!-- mode:给组件添加 mode 属性设置为了 region,从而变成省市区选择器 --><!-- value:要求是一个数组,表示选中的省市区,默认选中每一列的第一个值 --><!-- bindchange:来监听属性值的改变,也就是获取选中的省市区 --><pickermode="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

Page({// coding...// 省市区选择onAddressChange(event) {const [provinceCode, cityCode, districtCode] = event.detail.codeconst [provinceName, cityName, districtName] = event.detail.value// 存储省市区对应的编码this.setData({provinceCode,provinceName,cityCode,cityName,districtName,districtCode})}// coding...
})

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

思路分析:

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

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

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

实现步骤:

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

落地代码:

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 中进行配置

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

getLocation 使用:

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

chooseLocation 使用:

// 地理定位
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() 必须用户发生点击行为后,才可以跳转到设置页进行授权信息管理。
// 获取用户地理位置信息
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. 安全域名设置
    • 在小程序管理后台 -> 开发 -> 开发管理 -> 开发设置 -> “服务器域名” 中设置 request 合法域名
    • 添加 https://apis.map.qq.com

详细步骤:

  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 核心类

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

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

    // 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_infothis.setData({// 省级: 前两位有值,后4位置0,如,河北省: 130000provinceCode: 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. 详细地址不能为空

正则:

// 验证收货人,是否只包含大小写字母、数字和中文字符
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

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) returnconsole.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

// 新增或修改地址
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

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

<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

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

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

// 去编辑页面
toEdit(event) {// 需要编辑的收货地址const { id } = event.target.datasetwx.navigateTo({url: `/modules/settingModule/pages/address/add/index?id=${id}`})
}

➡️ /modules/settingModule/pages/address/add/index.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

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

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

// 删除收货地址
async delAddress(e) {const { id } = e.target.datasetawait reqDelAddress(id)this.getAddressList()
}

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

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

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

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

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

在这里插入图片描述

实现思路:

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

落地代码:

➡️ /behavior/swipeCellBahavior.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

<view class="container address-list" bindtap="onSwipeCellPageTap"><van-swipe-cellright-width="{{ 65 }}"
+     data-id="{{ item.id }}"
+     bind:open="onSwipeCellOpen"
+     bind:click="onSwipeCellClick"><!-- 代码略... --></van-swipe-cell></view>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.bcls.cn/OYqN/9792.shtml

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

应用存储与持久化数据卷

1、PV 引入场景&#xff1a; ① Deployment 管理的 pod&#xff0c;在做镜像升级的过程中&#xff0c;会产生新的 pod并且删除旧的 pod &#xff0c;新旧 pod 之间如何复用数据&#xff1f; ② 宿主机宕机的时候&#xff0c;如何实现带卷迁移&#xff1f; ③ 多个 pod 之间&…

亚信安慧AntDB-M的扩展功能(三)

销毁函数&#xff1a; void My_SUM_deinit(UDF_INIT *initid) { //清理工作 } 假设编译生成的动态库名字是&#xff1a;my_sum_udf.so。 使用CREATE FUNCTION命令创建函数&#xff1a; CREATE FUNCTION My_SUM RETURNS INTEGER SONAME my_sum_udf.so; 使用UDF: SELECT My…

模型优化_如何提高网络/模型的泛化能力?(全面)

目录 1. 以数据为中心的泛化方法 1.1 使用更多数据 1.2 做好数据预处理 特征工程 1.3 数据增强 1.4 调整数据分布 2. 以模型为中心的泛化方法 2.1 使用更大批次 超参数调优 2.2 调整目标函数 2.3 调整网络结构 2.4 屏蔽网络节点 2.5 权值正则化 2.6 偏差-方差权衡…

雾锁王国服务器官方配置要求说明

雾锁王国/Enshrouded服务器CPU内存配置如何选择&#xff1f;阿里云服务器网aliyunfuwuqi.com建议选择8核32G配置&#xff0c;支持4人玩家畅玩&#xff0c;自带10M公网带宽&#xff0c;1个月90元&#xff0c;3个月271元&#xff0c;幻兽帕鲁服务器申请页面 https://t.aliyun.com…

【BUUCTF web】通关1.0

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

微信为什么使用 SQLite 保存聊天记录?

SQLite 是一个被大家低估的数据库&#xff0c;但有些人认为它是一个不适合生产环境使用的玩具数据库。事实上&#xff0c;SQLite 是一个非常可靠的数据库&#xff0c;它可以处理 TB 级的数据&#xff0c;但它没有网络层。接下来&#xff0c;本文将与大家共同探讨 SQLite 在过去…

房贷计算器微信小程序原生语言

微信小程序: 房贷计算器 效果: 输入 300万 结果 还款明细 一共有3个页面 1、输入页面 2、结果页面 3、详情页面 1 index页面 index.wxml文件 <view class="text-black"><!--房屋总价--><view class="cu-bar bg-white solid-bottom"&…

ZABBIX修改web界面的 “支持“,“帮助”,“Integrations“。等菜单按钮,百试百灵,删除修改Help,Support菜单

♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ ♥ **ZABBIX修改web界面的 “支持”&#xff0c;“帮助”,“Integrations”。等菜单按钮&#xff0c…

十三、Qt多线程与线程安全

一、多线程程序 QThread类提供了管理线程的方法&#xff1a;一个对象管理一个线程一般从QThread继承一个自定义类&#xff0c;重载run函数 1、实现程序 &#xff08;1&#xff09;创建项目&#xff0c;基于QDialog &#xff08;2&#xff09;添加类&#xff0c;修改基于QThr…

提升智能客服机器人的语义理解能力:理解用户的语义和意图

智能客服机器人的发展已经成为现代服务业的一大亮点。它们不仅能够提供724小时不间断的服务&#xff0c;而且能够处理大量的用户请求&#xff0c;大大提高了服务效率。然而&#xff0c;尽管智能客服机器人的技术已经取得了显著的进步&#xff0c;但其语义理解能力仍有待提高。为…

Crawler爬虫基础知识

本来其实不知道爬虫的意义的&#xff0c;但是发现爬虫在信息收集的那一方面好像挺重要&#xff01;&#xff01; 那么就来浅学一下吧&#xff01;&#xff01;&#xff01; 1.基本的储备 对于爬虫&#xff0c;我们一般都是用的python去编写脚本 &#xff0c;其中还要导入…

阿里云启动实例进入了急救模式解决办法

相关文档 问题描述 通过远程连接软件无法登录Linux实例&#xff0c;通过使用管理终端连接Linux实例远程连接时&#xff0c;发现系统进入到急救模式&#xff08;emergency mode&#xff09;&#xff0c;且出现报错。 CentOS实例报如下错误。 systemctl default to try again…

模拟算法题练习(一)

模拟算法介绍&#xff1a; 模拟算法通过模拟实际情况来解决问题&#xff0c;一般容易理解但是实现起来比较复杂&#xff0c;有很多需要注意的细节&#xff0c;或者是一些所谓很“麻模“的东西。 模拟题一般不涉及太难的算法&#xff0c;一般就是由较多的简单但是不好处理的部…

Java——建造者模式(Builder)

建造者模式&#xff08;Builder&#xff09; 1、建造者模式的定义 将一个复杂对象的构建与它的表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 Builder模式是一步一步创建一个复杂对象的创建型模式&#xff0c;它允许使用者在不知道内部建造细节的情况下&…

Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

【计算机】本科考研还是就业?

其实现在很多计算机专业的学生考研&#xff0c;也是无奈的选择 技术发展日新月异&#xff0c;而在本科阶段&#xff0c;大家学着落后的技术&#xff0c;出来找工作自然会碰壁。而且现在用人单位的门槛越来越高&#xff0c;学历默认研究生起步&#xff0c;面试一般都是三轮起步…

Linux 下安装Jupyter

pip3 install jupyter pip3 install ipython -------------------------------------------- pip3 install jupyterlab jupyter lab pip3 list | grep jupyterlab 启动&#xff1a; python3 -m jupyter lab 2.安装朱皮特 pip3 install -i https://pypi.douban.com/simpl…

安卓开发1- android stdio环境搭建

安卓开发1-android stdio环境搭建 Jdk环境搭建 1. 准备Jdk,这边已经准备好了jdk1.8.0,该文件直接使用即可 2. 系统变量添加 %JAVA_HOME%\bin JAVA_HOME 3. 系统变量&#xff0c;Path路径添加 4. 添加完成后&#xff0c;输入命令javac / java -version&#xff0c;验证环…

初学者如何使用QT新建一个包含UI界面的C++项目

文章目录 一、下载并安装QT51、下载安装包2、注册/登录账号3、安装qt6 二、新建QT Widget项目1、新建项目并且运行2、易错点&#xff1a;可能运行成功得到UI界面但是会报错&#xff08;原因是使用了中文路径&#xff09; 一、下载并安装QT5 1、下载安装包 进入下载网址 Windo…

DOM 创建节点、添加节点和删除节点

创建元素节点 document.createElement(‘标签名’) 创建文本节点document.createTextNode ( 内容 ) 根据传入的标签名创建出一个空的元素对象创建出来的默认不显示&#xff0c;要成为别人的子元素才能显示&#xff0c;所以要结合appendChild使用 添加节点&#xff08;后面&am…
推荐文章