做兼职调查哪个网站好,s.w.g wordpress,邢台网站建设网站,网站定制开发优点购物车
01. 购物车-封装购物车接口 API
思路分析#xff1a;
为了方便后续进行购物车模块的开发#xff0c;我们在这一节将购物车所有的接口封装成接口 API 函数
落地代码#xff1a;
import http from ../utils/http/*** description 获取购物车列表数据* returns Pro…购物车
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 代表是立即购买否则是加入购物车
产品需求 如果点击的是加入购物车需要将当前商品加入到购物车 如果点击的是立即购买需要跳转到结算支付页面立即购买该商品 如果是立即购买不支持购买多个商品
结构分析
点击立即购买和加入购物车的时候通过 show 属性控制弹框的隐藏和展示
!-- 商品的底部商品导航 --
van-goods-action!-- coding... --van-goods-action-button text加入购物车 typewarning bindtaphandleAddcart /van-goods-action-button text立即购买 bindtaphandeGotoBuy /
/van-goods-action!-- 加入购物车、立即购买弹框 --
!-- show 控制弹框的隐藏和展示 --
!-- bind:close 点击关闭弹框时触发的回调 --
van-action-sheet show{{ show }} bind:closeonCloseview classsheet-wrapper!-- 代码略... --!-- 购买数量弹框 --view classbuy-btn wx:if{{ buyNow 0 }}!-- Stepper 步进器由增加按钮、减少按钮和输入框组成控制购买数量 --van-stepper value{{ count }} bind:changeonChangeGoodsCount //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/userstoreexport const userBehavior BehaviorWithStore({storeBindings: {store: userStore,fields: [token]}
})
➡️ /behaviors/userBehavior.js
import { reqGoodsInfo } from /api/goods
import { reqAddCart } from /api/cartimport { userBehavior } from /behaviors/userBehaviorPage({behaviors: [userBehavior],// 代码略...
})
04. 加入购物车和立即购买区分处理
思路分析
点击加入购物车以及立即购买以后需要先判断是否进行了登录如果用户没有登录过需要先跳转到登录页面进行登录。
如果点击的是 加入购物车我们只需要调用 加入购物车 接口即可 (需要获取商品的 ID 、购买数量、祝福语)
如果点击的是 立即购买我们需要携带参数跳转到商品结算页面 (获取商品的 ID 以及 祝福语跳转到结算页面)
购买数量的限制有 4 个限制这 4 个限制直接使用 Vant 组件提供的属性进行限制即可
必须是正整数最小是1最大是200若输入小于1则重置为1若输入大于200则重置为200若输入的是其他值则重置为1
实现步骤
给 Stepper 步进器组件通过value设置输入值同时绑定change事件并将值同步到 data 中根据接口文档导入封装的购物车的接口 API点击弹框按钮的时候判断点击的加入购物车还是立即购买执行不同的操作
落地代码
➡️ /modules/goodsModule/pages/detail/detail.html
van-steppervalue{{ count }}integermin1max200bind:changeonChangeGoodsCount
/➡️ /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. 加入购物车-展示购物车购买数量
思路分析
判断用户是否进行了登录。
如果没有登录过则不展示购物车商品的数量。
如果用户登录过则需要展示购物车商品的数量则获取购物车列表数据通过累加计算得出商品购买数量
实现步骤
进入商品详情调用方法在方法中判断token是否存在如何存在则获取购物车列表数据通过累加计算得出商品购买数量展示购买的数量不存在不执行任何逻辑
落地代码
➡️ /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-bindingsimport { userStore } from /stores/userstoreimport { reqCartList } from /api/cart ComponentWithStore({storeBindings: {store: userStore,fields: [token]},// 组件的初始数据data: {cartList: [],emptyDes: 还没有添加商品快去添加吧}, // 组件的方法列表methods: {// 处理页面的展示async showTipList() {// 将 token 进行解构const { token } this.dataconsole.log(token)},onShow() {this.showTipList()}}
})
07. 购物车-获取并渲染购物车列表
思路分析 如果没有进行登录购物车页面需要展示文案您尚未登录点击登录获取更多权益 如果用户进行登录获取购物车列表数据 购物车没有商品展示文案 还没有添加商品快去添加吧 购物车列表有数据需要使用数据对页面进行渲染
实现步骤
导入封装好的获取列表数据的 API 函数在 onShow 钩子中根据产品的需求处理页面的提示在获取到数据以后使用后端返回的数据对页面进行渲染
落地代码
➡️/pages/cart/cart.js
import { ComponentWithStore } from mobx-miniprogram-bindings
import { userStore } from /stores/userstore
import { reqCartList } from /api/cartComponentWithStore({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
viewviewwx:if{{ token cartList.length }}classcontainer goods-wrapbindtaponSwipeCellPageTapview classcart-wrapview classgoods-item wx:for{{ cartList }} wx:keyidvan-swipe-cell classgoods-swipe right-width{{ 65 }}view classgoods-infoview classleftvan-checkboxchecked-color#FA4126value{{ item.checked }}/van-checkbox/viewview classmidimage classimg src{{ item.imageUrl }} //viewview classrightview classtitle {{ item.name }} /viewview classbuyview classpriceview classsymbol¥/viewview classnum{{ item.price }}/view/viewview classbuy-btnvan-stepper value{{ item.count }} //view/view/view/viewview slotright classvan-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/viewvan-empty wx:else description{{ emptyDes }}navigator url/pages/index/index wx:if{{ token }}van-button round typedanger classbottom-button去购物/van-button/navigatornavigator url/pages/login/login wx:elsevan-button round typedanger classbottom-button去登录/van-button/navigator/van-empty
/view
08. 购物车-更新商品的购买状态
思路分析
点击商品的复选框时更新商品的购买状态。
获取商品最新的购买状态将最新的状态同步到服务器(需要调用封装的接口 API 函数0 不购买1 购买)在服务器更新状态更新成功以后将本地的数据一并改变。
实现步骤
导入封装好的获取列表数据的 API 函数当点击切换切换商品状态的时候调用 reqUpdateGoodStatus并传参在更新成功将本地的数据一并改变。
落地代码
➡️ /pages/cart/cart.wxml
van-checkboxchecked-color#FA4126value{{ item.isChecked }}bind:changeupdateCheckeddata-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/cartComponent({// 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实现步骤
在 cart 组件中引入 miniprogram-computed 然后再 behaviors 中进行注册新建 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-bar10. 购物车-实现全选和全不选功能
思路分析
点击全选控制所有商品的选中与全不选效果
点击全选按钮获取全选按钮的选中状态(true, false)同时控制所有商品的选中与全不选效果在获取到全选按钮状态以后同时需要将状态同步给服务器 (1 是全选0 是全不选)在服务器更新成功以后需要将本地的购物车商品选中状态也进行改变
实现步骤
导入封装好的全选的 API 函数当点击全选和全不选按钮的时候调用 reqCheckAll并传参在更新成功将本地的数据一并改变。
落地代码
➡️ /pages/cart/cart.wxml
!-- 底部工具栏 --
van-submit-bar price{{ 3050 }} button-text去结算 tip{{ true }}van-checkboxvalue{{ selectAllStatus }}checked-color#FA4126bind:changechangeAllStatus全选/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最大是200如果输入的值大于200输入框购买数量需要重置为200输入的值不合法或者小于1还原为之前的购买数量
const reg /^([1-9]|[1-9]\d|1\d{2}|200)$/实现步骤
给输入框绑定监听值是否改变的事件同时传递商品的 ID id 和 商品的购买之前的购买数量 num在事件处理程序中获取到最新的数据然后进行差值的运算发送请求即可
落地代码
➡️ /pages/cart/cart.wxml
van-stepperintegermin1max200value{{ item.count }}data-id{{ item.goodsId }}data-oldbuynum{{ item.count }}data-index{{ index }}bindchangechangeBuyNum
/➡️ /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 来实现商品合计的功能
实现步骤
在 computed 配置项新增 totalPrice 函数用来计算商品价格总和
落地代码
➡️ /pages/cart/cart.wxml
!-- 底部工具栏 --
van-submit-barwx:if{{ cartList.length }}price{{ totalPrice }}button-text去结算tip{{ true }}
van-checkboxvalue{{ selectAllStatus }}checked-color#FA4126bindchangeselectAllStatus全选/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. 购物车-删除购物车中的商品
思路分析
点击删除按钮的时候需要将对应的购物车商品进行删除
实现步骤
导入封装的接口 API 函数同时导入处理删除自动关闭效果的 behaviors 并进行注册在点击删除以后调用 API 函数在删除购物车商品成功以后给用户提示
落地代码
➡️ /pages/cart/components/cart.wxml view bindtaponSwipeCellPage!-- 代码略 --van-swipe-cellclassgoods-swiperight-width{{ 65 }}idswipe-cell-{{ item.goodsId }}bind:openswipeCellOpenbind:clickonSwipeCellClickvan-cell-group border{{ false }}view classgoods-infoview classleftvan-checkboxchecked-color#FA4126value{{ item.isChecked }}bindchangeupdateCheckeddata-id{{ item.goodsId }}data-index{{ index }}/van-checkbox/viewview classmidimage classimg src{{ item.imageUrl }} //viewview classrightview classtitle {{ item.name }} /viewview classbuyview classpriceview classsymbol¥/viewview classnum{{ item.price }}/view/viewview classbuy-btnvan-steppermin1max200integervalue{{ item.count }}data-id{{ item.goodsId }}data-index{{ index }}data-oldbuynum{{ item.count }}bindchangechangeBuyNum//view/view/view/view/van-cell-groupviewslotrightclassvan-swipe-cell__rightbindtapdelCartGoodsdata-id{{ item.goodsId }}删除/view/van-swipe-cell!-- 代码略 --
/view➡️ /pages/cart/components/cart.wxml
// 导入接口 API 函数
import {reqCartList,reqUpdateChecked,reqCheckAllStatus,reqAddCart,reqDelCartGoods
} from /api/cart // 导入让删除滑块自动弹回的 behaviorimport { swipeCellBehavior } from /behaviors/swipeCellComponentWithStore({// 注册 behaviorbehaviors: [swipeCellBehavior, computedBehavior],// 组件的方法列表methods: {// coding... // 删除购物车中的商品async delCartGoods(event) {// 获取需要删除商品的 idconst { id } event.currentTarget.dataset// 询问用户是否删除该商品const modalRes await wx.modal({content: 您确认删除该商品吗 ?})if (modalRes) {await reqDelCartGoods(id)this.showTipGetList()}}, onHide() {// 在页面隐藏的时候需要让删除滑块自动弹回this.onSwipeCellCommonClick()}}
})