微信小程序 ---- 慕尚花坊 購物車

購物車

01. 購物車-封裝購物車接口 API

思路分析:

為了方便后續進行購物車模塊的開發,我們在這一節將購物車所有的接口封裝成接口 API 函數

落地代碼:

import http from '../utils/http'/*** @description 獲取購物車列表數據* @returns Promise*/
export const reqCartList = () => {return http.get('/mall-api/cart/getCartList')
}/*** @description 加入購物車* @param {*} data* @returns Promise*/
export const reqAddCart = (data) => {return http.get(`/cart/addToCart/${data.goodsId}/${data.count}`, data)
}/*** @description 更新商品的選中狀態* @param {*} goodsId 商品 id* @param {*} isChecked 商品的選中狀態* @returns Promise*/
export const reqUpdateChecked = (goodsId, isChecked) => {return http.get(`/cart/checkCart/${goodsId}/${isChecked}`)
}/*** @description 全選和全不選* @param {*} isChecked 商品的選中狀態* @returns Promise*/
export const reqCheckAllCart = (isChecked) => {return http.get(`/cart/checkAllCart/${isChecked}`)
}/*** @description 刪除購物車商品* @param {*} goodsId 商品 id* @returns Promise*/
export const reqDelCart = (goodsId) => {return http.get(`/cart/delete/${goodsId}`)
}

02. 加入購物車-模板分析和渲染

業務介紹

點擊加入購物車和立即購買的時候,展示購物彈框,在彈框中需要用戶選擇購買數量和祝福語

點擊加入購物車和立即購買,觸發的是同一個彈框。

因此點擊彈框中的確定按鈕時,我們需要區分當前是加入購物車操作還是立即購買操作。

這時候定義一個狀態 buyNow 做區分,buyNow 等于 1 代表是立即購買,否則是加入購物車

產品需求

  1. 如果點擊的是加入購物車,需要將當前商品加入到購物車

  2. 如果點擊的是立即購買,需要跳轉到結算支付頁面,立即購買該商品

  3. 如果是立即購買,不支持購買多個商品

結構分析

點擊立即購買和加入購物車的時候,通過 show 屬性,控制彈框的隱藏和展示

<!-- 商品的底部商品導航 -->
<van-goods-action><!-- coding... -->
+   <van-goods-action-button text="加入購物車" type="warning" bindtap="handleAddcart" />
+   <van-goods-action-button text="立即購買" bindtap="handeGotoBuy" />
</van-goods-action><!-- 加入購物車、立即購買彈框 -->
<!-- show 控制彈框的隱藏和展示 -->
<!-- bind:close 點擊關閉彈框時觸發的回調 -->
<van-action-sheet show="{{ show }}" bind:close="onClose"><view class="sheet-wrapper"><!-- 代碼略... --><!-- 購買數量彈框 -->
+     <view class="buy-btn" wx:if="{{ buyNow === 0 }}"><!-- Stepper 步進器,由增加按鈕、減少按鈕和輸入框組成,控制購買數量 --><van-stepper value="{{ count }}" bind:change="onChangeGoodsCount" /></view><!-- 代碼略... --></view>
</van-action-sheet>

點擊立即購買和加入購物車的時候,通過 buyNow 屬性,來區分是進行的某種操作

Page({// 頁面的初始數據data: {goodsInfo: {}, // 商品詳情show: false, // 加入購物車和立即購買時顯示的彈框count: 1, // 商品購買數量,默認是 1blessing: '', // 祝福語
+     buyNow: '' // 是否立即購買},// 加入購物車handleAddcart() {this.setData({show: true,
+       buyNow: 0})},// 立即購買handeGotoBuy() {this.setData({show: true,
+       buyNow: 1})},// 代碼略...
})

03. 加入購物車-關聯 Store 對象

思路分析:

當用戶點擊加入購物車 或者 立即購買時,需要判斷用戶是否進行了登錄。

我們需要使用 Token 進行判斷,因此需要讓頁面和 Store 對象建立關聯。

這時候可以使用 BehaviorWithStore 讓頁面 和 Store 對象建立關聯。

落地代碼:

?? /behaviors/userBehavior.js

// 導入 BehaviorWithStore 讓頁面和 Store 對象建立關聯
import { BehaviorWithStore } from 'mobx-miniprogram-bindings'
// 導入用戶 Store
import { userStore } from '@/stores/userstore'export const userBehavior = BehaviorWithStore({storeBindings: {store: userStore,fields: ['token']}
})

?? /behaviors/userBehavior.js

import { reqGoodsInfo } from '@/api/goods'
import { reqAddCart } from '@/api/cart'
+ import { userBehavior } from '@/behaviors/userBehavior'Page({
+   behaviors: [userBehavior],// 代碼略...
})

04. 加入購物車和立即購買區分處理

思路分析:

點擊加入購物車以及立即購買以后,需要先判斷是否進行了登錄,如果用戶沒有登錄過,需要先跳轉到登錄頁面進行登錄。

如果點擊的是 加入購物車,我們只需要調用 加入購物車 接口即可 (需要獲取商品的 ID 、購買數量、祝福語)

如果點擊的是 立即購買,我們需要攜帶參數跳轉到商品結算頁面 (獲取商品的 ID 以及 祝福語跳轉到結算頁面)

購買數量的限制有 4 個限制,這 4 個限制直接使用 Vant 組件提供的屬性進行限制即可:

  1. 必須是正整數,最小是1,最大是200
  2. 若輸入小于1,則重置為1
  3. 若輸入大于200,則重置為200
  4. 若輸入的是其他值,則重置為1

實現步驟:

  1. Stepper 步進器組件,通過value設置輸入值,同時綁定change事件,并將值同步到 data
  2. 根據接口文檔,導入封裝的購物車的接口 API
  3. 點擊彈框按鈕的時候,判斷點擊的加入購物車還是立即購買,執行不同的操作

落地代碼:

?? /modules/goodsModule/pages/detail/detail.html

<van-steppervalue="{{ count }}"
+  integer
+  min="1"
+  max="200"bind:change="onChangeGoodsCount"
/>

?? /modules/goodsModule/pages/detail/detail.js

// 監聽是否更改了購買數量
onChangeGoodsCount(event) {// 將最新的購買數量同步到 datathis.setData({count: Number(event.detail)})
},// 彈框的確定按鈕
async handleSubmit() {// 解構獲取數據const { token, count, blessing, buyNow } = this.dataconst goodsId = this.goodsId// 如果沒有 token ,讓用戶新登錄if (!this.data.token) {wx.navigateTo({url: '/pages/login/login'})return}// 將用戶輸入的值轉成 Number 類型const count = Number(event.detail)// 驗證購買數量的正則const reg = /^([1-9]|[1-9]\d|1\d{2}|200)$/// 使用正則驗證const res = reg.test(count)// 如果驗證沒有通過,直接返回,不執行后續的邏輯if (!res) return// 加入購物車if (buyNow === 0) {// 加入購物車const res = await reqAddGood({ goodsId, count, blessing })if (res.code === 200) {wx.showToast({title: '加入購物車成功'})this.setData({show: false})}} else {// 立即購買wx.navigateTo({url: `/pages/order/detail/index?goodsId=${goodsId}&blessing=${blessing}`})}
}

05. 加入購物車-展示購物車購買數量

思路分析

判斷用戶是否進行了登錄。

如果沒有登錄過,則不展示購物車商品的數量。

如果用戶登錄過,則需要展示購物車商品的數量,則獲取購物車列表數據,通過累加計算得出商品購買數量

實現步驟

  1. 進入商品詳情,調用方法,在方法中判斷token是否存在
  2. 如何存在,則獲取購物車列表數據,通過累加計算得出商品購買數量,展示購買的數量
  3. 不存在,不執行任何邏輯,

落地代碼

?? /modules/goodsModule/pages/detail/detail.js

Page({data: {// coding...
+     allCount: '' // 購物車商品總數量},// 彈框的確定按鈕async handleSubmit() {// 如果沒有 token ,讓用戶新登錄if (!this.data.token) {wx.navigateTo({url: '/pages/login/login'})return}// 解構獲取數據const { count, blessing, allCount } = this.dataconst goodsId = this.goodsId// 加入購物車if (this.data.buyNow === 0) {// 加入購物車const res = await reqAddCart({ goodsId, count, blessing })if (res.code === 200) {wx.toast({title: '加入購物車成功',icon: 'success',mask: false})+         // 購物車購買數量合計
+         this.getCartCount()this.setData({show: false})}} else {// 立即購買wx.navigateTo({url: `/pages/order/detail/detail?goodsId=${goodsId}&blessing=${blessing}`})}},+   // 計算購買數量
+   async getCartCount() {
+     // 如果沒有 token ,說明用戶是第一次訪問小程序,沒有進行登錄過
+     if (!this.data.token) return
+ 
+     // 獲取購物的商品
+     const res = await reqCartList()
+ 
+     if (res.data.length !== 0) {
+       // 購物車商品累加
+       let allCount = 0
+ 
+       // 獲取購物車商品數量
+       res.data.forEach((item) => {
+         allCount += item.count
+       })
+ 
+       // 將購物車購買數量賦值
+       this.setData({
+         // 展示的數據要求是字符串
+         allCount: (allCount > 99 ? '99+' : allCount) + ''
+       })
+     }
+   },onLoad(options) {// 接收傳遞的商品 ID,并且將 商品 ID 掛載到 this 上面this.goodsId = options.goodsId// 調用獲取商品詳情數據的方法this.getGoodsInfo()+     // 計算購買數量
+     this.getCartCount()}// coding...
})

06. 購物車-購物車關聯 Store 對象

思路分析:

當用戶進入購物車頁面時時,需要判斷用戶是否進行了登錄來控制頁面的展示效果

這時候我們就需要使用 Token 進行判斷,因此需要讓頁面和 Store 對象建立關聯。

因為購物車頁面采用的 Component 方法進行構建

這時候可以使用 ComponentWithStore 讓頁面 和 Store 對象建立關聯。

落地代碼:

??/pages/cart/components/cart.js

+ import { ComponentWithStore } from 'mobx-miniprogram-bindings'
+ import { userStore } from '@/stores/userstore'
+ import { reqCartList } from '@/api/cart'+ ComponentWithStore({
+   storeBindings: {
+     store: userStore,
+     fields: ['token']
+   },// 組件的初始數據data: {cartList: [],emptyDes: '還沒有添加商品,快去添加吧~'},+   // 組件的方法列表
+   methods: {
+     // 處理頁面的展示
+     async showTipList() {
+       // 將 token 進行解構
+       const { token } = this.data
+
+ 		console.log(token)
+     },onShow() {
+       this.showTipList()}}
})

07. 購物車-獲取并渲染購物車列表

思路分析:

  1. 如果沒有進行登錄,購物車頁面需要展示文案:您尚未登錄,點擊登錄獲取更多權益

  2. 如果用戶進行登錄,獲取購物車列表數據

    • 購物車沒有商品,展示文案: 還沒有添加商品,快去添加吧~

    • 購物車列表有數據,需要使用數據對頁面進行渲染

實現步驟:

  1. 導入封裝好的獲取列表數據的 API 函數
  2. onShow 鉤子中,根據產品的需求,處理頁面的提示
  3. 在獲取到數據以后,使用后端返回的數據對頁面進行渲染

落地代碼:

??/pages/cart/cart.js

import { ComponentWithStore } from 'mobx-miniprogram-bindings'
import { userStore } from '@/stores/userstore'
import { reqCartList } from '@/api/cart'ComponentWithStore({storeBindings: {store: userStore,fields: ['token']},// 組件的初始數據data: {cartList: [],emptyDes: '還沒有添加商品,快去添加吧~'},// 組件的方法列表methods: {
+     // 獲取購物車列表數據 + 處理頁面的展示
+     async showTipGetList() {
+       // 將 token 進行解構
+       const { token } = this.data
+ 
+       // 1. 如果沒有登錄,購物車列表,展示文案:您尚未登錄,點擊登錄獲取更多權益
+       if (!token) {
+         this.setData({
+           emptyDes: '您尚未登錄,點擊登錄獲取更多權益',
+           cartList: []
+         })
+ 
+         return
+       }
+ 
+       // 獲取商品列表數據
+       const { data: cartList, code } = await reqCartList()
+ 
+       if (code === 200) {
+         // 2. 如果用戶登錄,購物車列表為空,展示文案: 還沒有添加商品,快去添加吧~
+         this.setData({
+           cartList,
+           emptyDes: cartList === 0 && '還沒有添加商品,快去添加吧~'
+         })
+       }
+     },// 頁面展示時觸發onShow() {
+       this.showTipGetList()}}
})

??/pages/cart/components/cart.wxml

<view><viewwx:if="{{ token && cartList.length }}"class="container goods-wrap"bindtap="onSwipeCellPageTap"><view class="cart-wrap">
+       <view class="goods-item" wx:for="{{ cartList }}" wx:key="id"><van-swipe-cell class="goods-swipe" right-width="{{ 65 }}"><view class="goods-info"><view class="left"><van-checkboxchecked-color="#FA4126"
+                 value="{{ item.checked }}"></van-checkbox></view><view class="mid">
+               <image class="img" src="{{ item.imageUrl }}" /></view><view class="right">
+               <view class="title"> {{ item.name }} </view><view class="buy"><view class="price"><view class="symbol"></view>
+                   <view class="num">{{ item.price }}</view></view><view class="buy-btn">
+                   <van-stepper value="{{ item.count }}" /></view></view></view></view><view slot="right" class="van-swipe-cell__right">刪除</view></van-swipe-cell></view></view><!-- 底部工具欄 --><van-submit-bar price="{{ 3050 }}" button-text="去結算" tip="{{ true }}"><van-checkbox value="{{ true }}" checked-color="#FA4126"> 全選 </van-checkbox></van-submit-bar></view><van-empty wx:else description="{{ emptyDes }}">
+     <navigator url="/pages/index/index" wx:if="{{ token }}">
+       <van-button round type="danger" class="bottom-button">去購物</van-button>
+     </navigator>
+ 
+     <navigator url="/pages/login/login" wx:else>
+       <van-button round type="danger" class="bottom-button">去登錄</van-button>
+     </navigator></van-empty>
</view>

08. 購物車-更新商品的購買狀態

思路分析:

點擊商品的復選框時,更新商品的購買狀態。

  1. 獲取商品最新的購買狀態,將最新的狀態同步到服務器(需要調用封裝的接口 API 函數,0 不購買,1 購買)
  2. 在服務器更新狀態更新成功以后,將本地的數據一并改變。

實現步驟:

  1. 導入封裝好的獲取列表數據的 API 函數
  2. 當點擊切換切換商品狀態的時候,調用 reqUpdateGoodStatus,并傳參
  3. 在更新成功,將本地的數據一并改變。

落地代碼:

?? /pages/cart/cart.wxml

<van-checkboxchecked-color="#FA4126"
+   value="{{ item.isChecked }}"
+   bind:change="updateChecked"
+   data-id="{{ item.goodsId }}"
+   data-index="{{ index }}"
></van-checkbox>

?? /pages/cart/cart.js

import { ComponentWithStore } from 'mobx-miniprogram-bindings'
import { userStore } from '@/stores/userstore'+ import { reqCartList, reqUpdateChecked } from '@/api/cart'Component({// coding...// 組件的方法列表methods: {// 切換商品的選中狀態async updateChecked(event) {// 獲取最新的選中狀態const { detail } = event// 獲取商品的索引和 idconst { id, index } = event.target.dataset// 將最新的狀態格式化成后端所需要的數據格式const isChecked = detail ? 1 : 0// 調用接口,傳入參數,更新商品的狀態const res = await reqUpdateChecked(id, isChecked)// 如果數據更新成功,需要將本地的數據一同改變if (res.code === 200) {this.setData({[`cartList[${index}].isChecked`]: isChecked})}},// 獲取購物車列表數據async getCartList() {// coding...}}
})

09. 購物車-控制全選按鈕的選中狀態

思路分析:

購物車列表中每個商品的狀態 isCheckd 都是 1,說明每個商品都需要進行購買。

這時候就需要控制底部工具欄全選按鈕的選中效果。

基于購物車列表中已有的數據,產生一個新的數據,來控制全選按鈕的選中效果,可以使用 計算屬性 來實現。

安裝 框架拓展 computed

# 安裝并構建 框架拓展 computed
npm i miniprogram-computed

實現步驟:

  1. cart 組件中引入 miniprogram-computed ,然后再 behaviors 中進行注冊
  2. 新建 computed 配置項,新增 allStatus 函數用來判斷是否是全選

落地代碼:

?? /pages/cart/cart.js

import { ComponentWithStore } from 'mobx-miniprogram-bindings'
import { userStore } from '@/stores/userstore'
import { reqCartList, reqUpdateChecked } from '@/api/cart'+ const computedBehavior = require('miniprogram-computed').behaviorComponentWithStore({+   // 注冊計算屬性
+   behaviors: [computedBehavior],+   computed: {
+     // 判斷是否全選
+     // computed 函數中不能訪問 this ,只有 data 對象可供訪問
+     // 這個函數的返回值會被設置到 this.data.selectAllStatus 字段中
+     selectAllStatus(data) {
+       return (
+         data.cartList.length !== 0 && data.cartList.every((item) => item.isChecked === 1)
+       )
+     }
+   }// 其他代碼略...
})

?? /pages/cart/cart.wxml

<!-- 底部工具欄 -->
<van-submit-bar price="{{ 3050 }}" button-text="去結算" tip="{{ true }}">
+   <van-checkbox value="{{ selectAllStatus }}" checked-color="#FA4126">全選</van-checkbox>
</van-submit-bar>

10. 購物車-實現全選和全不選功能

思路分析:

點擊全選,控制所有商品的選中與全不選效果

  1. 點擊全選按鈕,獲取全選按鈕的選中狀態(true, false),同時控制所有商品的選中與全不選效果
  2. 在獲取到全選按鈕狀態以后,同時需要將狀態同步給服務器 (1 是全選,0 是全不選)
  3. 在服務器更新成功以后,需要將本地的購物車商品選中狀態也進行改變

實現步驟:

  1. 導入封裝好的全選的 API 函數
  2. 當點擊全選和全不選按鈕的時候,調用 reqCheckAll,并傳參
  3. 在更新成功,將本地的數據一并改變。

落地代碼:

?? /pages/cart/cart.wxml

<!-- 底部工具欄 -->
<van-submit-bar price="{{ 3050 }}" button-text="去結算" tip="{{ true }}"><van-checkboxvalue="{{ selectAllStatus }}"checked-color="#FA4126"bind:change="changeAllStatus">全選</van-checkbox>
</van-submit-bar>

?? /pages/cart/cart.js

ComponentWithStore({// coding...methods: {// coding...// 全選和全不選功能async updateAllStatus(event) {// 獲取全選和全不選的狀態const isChecked = event.detail ? 1 : 0// 調用接口,更新服務器中商品的狀態const res = await reqCheckAllStatus(isChecked)// 如果更新成功,需要將本地的數據一同改變if (res.code === 200) {// 將數據進行拷貝const newCart = JSON.parse(JSON.stringify(this.data.cartList))// 將數據進行更改newCart.forEach((item) => (item.isChecked = isChecked))// 進行賦值this.setData({cartList: newCart})}},// coding...}})

11. 購物車-更新商品購買數量思路分析

思路分析:

在輸入框中輸入購買的數量,并**不是直接將輸入的數量同步給服務器,而是需要計算差值**,服務器端進行處理

差值的計算公式:

差值 = 新值 - 舊值例如:1. 原來是 1,用戶輸入 11, 差值是:11 - 1 = 10,傳遞給服務器的是:10,服務器接收到 10 + 1 = 11 
2. 原來是 11,用戶輸入 5, 差值是:5 - 11 = -6,傳遞給服務器的是:-6,服務器接收到 -6 + 11 = 5

📌 注意事項:

更新購買數量 和 加入購物車,使用的是同一個接口,為什么加入購物車沒有計算差值,

這是因為在加入購物車以后,服務器對商品購買數量直接進行了累加。

例如:之前購物車添加了某個商品,購買數量是 1 個,商品詳情又加入 1 個, 直接累加,在購物車顯示購買 2 個

12. 購物車-更新商品的購買數量

思路分析:

  1. 必須是正整數,最小是1,最大是200
  2. 如果輸入的值大于200,輸入框購買數量需要重置為200
  3. 輸入的值不合法或者小于1,還原為之前的購買數量
const reg = /^([1-9]|[1-9]\d|1\d{2}|200)$/

實現步驟:

  1. 給輸入框綁定監聽值是否改變的事件,同時傳遞商品的 ID id 和 商品的購買之前的購買數量 num
  2. 在事件處理程序中獲取到最新的數據,然后進行差值的運算
  3. 發送請求即可

落地代碼:

?? /pages/cart/cart.wxml

<van-stepper
+   integer
+   min="1"
+   max="200"value="{{ item.count }}"
+   data-id="{{ item.goodsId }}"
+   data-oldbuynum="{{ item.count }}"
+   data-index="{{ index }}"
+   bindchange="changeBuyNum"
/>

?? /pages/cart/cart.js

// 更新購買的數量
async changeBuyNum(event) {// 獲取最新的購買數量,// 如果用戶輸入的值大于 200,購買數量需要重置為 200// 如果不大于 200,直接返回用戶輸入的值let buynum = event.detail > 200 ? 200 : event.detail// 獲取商品的 ID 和 索引const { id: goodsId, index, oldbuynum } = event.target.dataset// 驗證用戶輸入的值,是否是 1 ~ 200 直接的正整數const reg = /^([1-9]|[1-9]\d|1\d{2}|200)$/// 對用戶輸入的值進行驗證const regRes = reg.test(buynum)// 如果驗證沒有通過,需要重置為之前的購買數量if (!regRes) {this.setData({[`cartList[${index}].count`]: oldbuynum})return}// 如果通過,需要計算差值,然后將差值發送給服務器,讓服務器進行邏輯處理const disCount = buynum - oldbuynum// 如果購買數量沒有發生改變,不發送請求if (disCount === 0) return// 發送請求:購買的數量 和 差值const res = await reqAddCart({ goodsId, count: disCount })// 服務器更新購買數量成功以后,更新本地的數據if (res.code === 200) {this.setData({[`cartList[${index}].count`]: buynum})}
}

13. 購物車-更新商品購買數量防抖

思路分析:

每次改變購物車購買數量的時候,都會觸發 changeBuyNum 事件處理程序,這會頻繁的向后端發送請求,給服務器造成壓力

我們希望用戶在輸入最終的購買數量,或者停止頻繁點擊加、減的以后在發送請求,在將購買數量同步到服務器。

這時候就需要使用 防抖 來進行代碼優化。

Licia 是實用 JavaScript 工具庫,該庫目前擁有超過 400 個模塊,同時支持瀏覽器、node 及小程序運行環境。可以極大地提高開發效率。

licia 官網

licia 中文使用文檔

落地代碼:

?? /pages/cart/cart.js

// 從 miniprogram-licia 導入防抖函數
import { debounce } from 'miniprogram-licia'// 更新購買的數量
+ changeBuyNum: debounce(async function (event) {
+   // 代碼略...
+ }, 500)

14. 購物車-購物車商品合計

思路分析:

在訂單提交欄位置,展示要購買商品的總金額。

需要判斷購物車中哪些商品被勾選,然后將勾選商品的價格進行累加。

當用戶更新了商品的狀態,或者更新了商品的購買數量,我們都需要重新計算訂單總金額。

我們需要基于購物車列表的數據,產生訂單總金額,在這里我們使用依然使用 computed 來實現商品合計的功能

實現步驟:

  1. computed 配置項,新增 totalPrice 函數用來計算商品價格總和

落地代碼:

?? /pages/cart/cart.wxml

<!-- 底部工具欄 -->
<van-submit-barwx:if="{{ cartList.length }}"price="{{ totalPrice }}"button-text="去結算"tip="{{ true }}"
><van-checkboxvalue="{{ selectAllStatus }}"checked-color="#FA4126"bindchange="selectAllStatus">全選</van-checkbox>
</van-submit-bar>

?? /pages/cart/cart.js

ComponentWithStore({// coding...// 定義計算屬性computed: {// coding...// 計算商品價格總和totalPrice(data) {let totalPrice = 0data.cartList.forEach((item) => {// 如果商品的 isChecked 屬性等于,說明該商品被選中的if (item.isChecked === 1) {totalPrice += item.count * item.price}})return totalPrice}},// coding...
})

15. 購物車-刪除購物車中的商品

思路分析:

點擊刪除按鈕的時候,需要將對應的購物車商品進行刪除

實現步驟:

  1. 導入封裝的接口 API 函數,同時導入處理刪除自動關閉效果的 behaviors 并進行注冊
  2. 在點擊刪除以后,調用 API 函數,在刪除購物車商品成功以后,給用戶提示

落地代碼:

?? /pages/cart/components/cart.wxml

+  <view bindtap="onSwipeCellPage"><!-- 代碼略 --><van-swipe-cellclass="goods-swipe"right-width="{{ 65 }}"
+     id="swipe-cell-{{ item.goodsId }}"
+     bind:open="swipeCellOpen"
+     bind:click="onSwipeCellClick"><van-cell-group border="{{ false }}"><view class="goods-info"><view class="left"><van-checkboxchecked-color="#FA4126"value="{{ item.isChecked }}"bindchange="updateChecked"data-id="{{ item.goodsId }}"data-index="{{ index }}"></van-checkbox></view><view class="mid"><image class="img" src="{{ item.imageUrl }}" /></view><view class="right"><view class="title"> {{ item.name }} </view><view class="buy"><view class="price"><view class="symbol"></view><view class="num">{{ item.price }}</view></view><view class="buy-btn"><van-steppermin="1"max="200"integervalue="{{ item.count }}"data-id="{{ item.goodsId }}"data-index="{{ index }}"data-oldbuynum="{{ item.count }}"bindchange="changeBuyNum"/></view></view></view></view></van-cell-group><viewslot="right"class="van-swipe-cell__right"
+       bindtap="delCartGoods"
+       data-id="{{ item.goodsId }}">刪除</view></van-swipe-cell><!-- 代碼略 -->
</view>

?? /pages/cart/components/cart.wxml

// 導入接口 API 函數
import {reqCartList,reqUpdateChecked,reqCheckAllStatus,reqAddCart,
+   reqDelCartGoods
} from '@/api/cart'+ // 導入讓刪除滑塊自動彈回的 behavior
+ import { swipeCellBehavior } from '@/behaviors/swipeCell'ComponentWithStore({// 注冊 behavior
+   behaviors: [swipeCellBehavior, computedBehavior],// 組件的方法列表methods: {// coding...+   // 刪除購物車中的商品
+   async delCartGoods(event) {
+     // 獲取需要刪除商品的 id
+     const { id } = event.currentTarget.dataset
+ 
+     // 詢問用戶是否刪除該商品
+     const modalRes = await wx.modal({
+       content: '您確認刪除該商品嗎 ?'
+     })
+ 
+     if (modalRes) {
+       await reqDelCartGoods(id)
+ 
+       this.showTipGetList()
+     }
+   },+     onHide() {
+       // 在頁面隱藏的時候,需要讓刪除滑塊自動彈回
+       this.onSwipeCellCommonClick()
+     }}
})

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711524.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711524.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711524.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue ElementUI 修改消息提示框樣式—messageBox 的大小

在窄屏模式下&#xff08;移動端或pda&#xff09;&#xff0c;提示框的寬度太寬&#xff0c;會出現顯示不完全的問題。 應當如何修改 ElementUI 的樣式呢&#xff1f; open() {this.$confirm(window.vm.$i18n.t("tips.conLogOut"),window.vm.$i18n.t("tips.tip…

11-Linux部署集群準備

Linux部署集群準備 介紹 在前面&#xff0c;我們所學習安裝的軟件&#xff0c;都是以單機模式運行的。 后續&#xff0c;我們將要學習大數據相關的軟件部署&#xff0c;所以后續我們所安裝的軟件服務&#xff0c;大多數都是以集群化&#xff08;多臺服務器共同工作&#xff…

【機器學習實戰1】泰坦尼克號:災難中的機器學習(一)數據預處理

&#x1f338;博主主頁&#xff1a;釉色清風&#x1f338;文章專欄&#xff1a;機器學習實戰&#x1f338;今日語錄&#xff1a;不要一直責怪過去的自己&#xff0c;她曾經站在霧里也很迷茫。 &#x1f33c;實戰項目簡介 本次項目是kaggle上的一個入門比賽 &#xff1a;Titani…

錨索測力計數據處理與分析:MCU自動測量單元的應用

錨索測力計作為一種重要的工程監測工具&#xff0c;在橋梁、大壩、隧道等結構物的健康監測中發揮著日益重要的作用。如何高效、準確地處理和分析&#xff0c;錨索測力計所獲取的數據成為了工程師們面臨的重要問題。近年來&#xff0c;隨著微控制器(MCU)技術的快速發展&#xff…

Python繪制實時空氣質量地圖

我們將使用 Google Colab 中的 Python 創建包含實時空氣質量數據的交互式地圖。 ??簡介 如果有人想查看地圖上各個傳感器的空氣質量分布情況,以檢查特定位置的空氣質量數據,該怎么辦?我接下來將解決這個問題。我們重點關注基于名為 PurpleAir 的密集空氣質量網絡來識別我們…

spring: HandlerInterceptor

文章目錄 一、什么是HandlerInterceptor二、應用示例 一、什么是HandlerInterceptor HandlerInterceptor 是 Spring 框架中的一個接口&#xff0c;用于攔截處理程序執行。在 Spring MVC 中&#xff0c;你可以使用 HandlerInterceptor 來在處理程序執行前、執行后或渲染視圖之前…

51-n皇后(回溯算法)

題目 按照國際象棋的規則&#xff0c;皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。 n 皇后問題 研究的是如何將 n 個皇后放置在 nn 的棋盤上&#xff0c;并且使皇后彼此之間不能相互攻擊。 給你一個整數 n &#xff0c;返回所有不同的 n 皇后問題 的解決方案。 每一…

前端開發項目必備神器之node工具整理

前言&#xff1a; 在我們開發項目中&#xff0c;node是我們必備的工具&#xff0c;在為了適應各種不同的開發需求的同時&#xff0c;node也有很多好用的插件提供給我們&#xff0c;這里整理個人的使用分享給大家&#xff01; 一、node相關 1、node官方網站&#xff0c;可以安裝…

模擬算法題練習(二)(DNA序列修正、無盡的石頭)

&#xff08;一、DNA序列修正&#xff09; 問題描述 在生物學中&#xff0c;DNA序列的相似性常被用來研究物種間的親緣關系。現在我們有兩條 DNA序列&#xff0c;每條序列由 A、C、G、T 四種字符組成&#xff0c;長度相同。但是現在我們記錄的 DNA序列存在錯誤&#xff0c;為了…

ubuntu基礎操作(1)-個人筆記

搜狗輸入法Linux官網-首頁搜狗輸入法for linux—支持全拼、簡拼、模糊音、云輸入、皮膚、中英混輸https://pinyin.sogou.com/linux 1.關閉sudo密碼&#xff1a; 終端&#xff08;ctrl alt t&#xff09;輸入 sudo visudo 打開visudo 找到 %sudo ALL(ALL:ALL) ALL 這一行…

羊大師分享,羊奶奶有哪些對健康有益的喝法?

羊大師分享&#xff0c;羊奶奶有哪些對健康有益的喝法&#xff1f; 羊奶奶有多種對健康有益的喝法&#xff0c;以下是一些建議&#xff1a; 直接飲用&#xff1a;將羊奶直接煮沸后飲用&#xff0c;可以保留羊奶中的營養成分&#xff0c;為身體提供全面的滋養。羊奶的豐富蛋白質…

代碼隨想錄算法訓練營第二十八天補|93.復原IP地址 ● 78.子集 ● 90.子集II

組合問題&#xff1a;集合內元素的組合&#xff0c;不同集合內元素的組合 分割問題&#xff1a;本質還是組合問題&#xff0c;注意一下如何分割字符串 回溯模板偽代碼 void backtracking(參數) {if (終止條件) {存放結果;return;}for (選擇&#xff1a;本層集合中元素&#xf…

Softmax

Softmax函數是一種在機器學習和深度學習中廣泛使用的激活函數&#xff0c;特別是在處理多分類問題時。它將一個含任意實數的向量轉換成一個概率分布&#xff0c;其中每個元素的值代表了屬于對應類別的概率。Softmax函數的輸出是所有可能類別的概率分布&#xff0c;這些概率的總…

【六袆 - MySQL】MySQL 5.5及更高版本中,InnoDB是新表的默認存儲引擎;

InnoDB 這是一個MySQL組件&#xff0c;結合了高性能和事務處理能力&#xff0c;以確保可靠性、健壯性和并發訪問。它體現了ACID設計哲學。它作為一個存儲引擎存在&#xff0c;處理使用ENGINEINNODB子句創建的或修改的表。請參閱第14章“InnoDB存儲引擎”以獲取有關架構細節和管…

【解決】虛幻導入FBX模型不是一個整體

問題&#xff1a; 現在有一個汽車的fbx模型&#xff0c;導入虛幻引擎&#xff0c;導入后變成了很多汽車零件模型。 解決&#xff1a; 把“合并網格體”勾選上&#xff0c;解決問題。

移動端app如何設計測試用例?

&#x1f345; 視頻學習&#xff1a;文末有免費的配套視頻可觀看 &#x1f345; 關注公眾號【互聯網雜貨鋪】&#xff0c;回復 1 &#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 1、用戶界面測試 布局和元素 驗證所 有UI元素&#xff08;如…

C語言拼接字符串操作

代碼解法不唯一&#xff0c;請在評論區留下你的實現方式和想法&#xff0c;我會將好的解法更新到文章中&#xff01;&#xff01; 要拼接 “字符串1” 和 “字符串2” &#xff0c;可以使用字符串連接操作。在C語言中&#xff0c;您可以使用strcat函數來將兩個字符串連接起來。…

Unity 佳能SDK 及數據獲取

1. 填寫信息跟官方申請SDK,大概1-2個工作日會郵件回復你 佳能(中國)- 佳定制(佳能影像產品),SDK,EDSDK,CCAPI,軟件開發包下載 2. 將SDK這兩個文件放到 Unity Plugins文件夾 3. 把CameraControl 下面只要是綠色的 .cs 文件都復制到Unity 中

ElasticSearch搜索引擎使用指南

一、ES數據基礎類型 1、數據類型 字符串 主要包括: text和keyword兩種類型&#xff0c;keyword代表精確值不會參與分詞&#xff0c;text類型的字符串會參與分詞處理 數值 包括: long, integer, short, byte, double, float 布爾值 boolean 時間 date 數組 數組類型不…

基于ssm學生公寓管理系統的設計與開發論文

學生公寓管理系統的設計與實現 摘要 如今&#xff0c;科學技術的力量越來越強大&#xff0c;通過結合較為成熟的計算機技術&#xff0c;促進了學校、醫療、商城等許多行業領域的發展。為了順應時代的變化&#xff0c;各行業結合互聯網、人工智能等技術&#xff0c;紛紛開展了…