首页 分享 微信小程序

微信小程序

来源:花匠小妙招 时间:2024-11-11 18:55

商品管理

01. 配置商品管理分包

思路分析:

随着项目功能的增加,项目体积也随着增大,从而影响小程序的加载速度,影响用户的体验。

因此我们需要将 商品列表 和 商品详情 功能配置成一个分包,

当用户在访问设置页面时,还预先加载 商品列表 和 商品详情 所在的分包

在分包后,通过查看代码依赖查看是否分包完成

注意事项

在配置好 商品列表 和 商品详情 的分包以后,需要更改页面中的跳转路径PS:可以利用项目全局搜索的功能,进行批量更改

实现步骤:

在 modules 目录下创建 goodModule 文件夹,用来存放商品管理分包在 app.json 的 subpackages 进行商品管理分包配置在 app.json 的 preloadRule 进行商品管理分包配置

落地代码:

➡️ app.json

{ "subPackages": [ { "root": "modules/settingModule", "name": "settingModule", "pages": [ "pages/address/add/index", "pages/address/list/index", "pages/profile/profile" ] }, + { + "root": "modules/goodModule", + "name": "goodModule", + "pages": ["pages/goods/list/list", "pages/goods/detail/detail"] } ], "preloadRule": { "pages/settings/settings": { "network": "all", "packages": ["settingModule"] }, + "pages/category/category": { + "network": "all", + "packages": ["goodModule"] + } } }

1234567891011121314151617181920212223242526272829 02. 封装商品模块接口 API

思路分析:

为了方便后续进行商品管理模块的开发,我们在这一节将商品管理所有的接口封装成接口 API 函数

落地代码:

➡️ api/goods.js

import http from '../utils/http' /** * @description 获取商品列表 * @return Promise */ export const reqGoodsList = ({ limit, page, ...reset }) => { return http.get(`/mall-api/goods/list/${page}/${limit}`, reset) } /** * @description 获取商品详情 * @param {*} goodsId 商品Id * @returns Promise */ export const reqGoodsInfo = (goodsId) => { return http.get(`/mall-api/goods/${goodsId}`) }

12345678910111213141516171819 03. 商品列表-准备列表请求参数

思路分析:

当用户点击了商品分类以后,需要获取对应分类的商品列表信息,因此我们需要先获取到该分类的 id,只要获取到 id 以后,才能向服务器获取对应分类的商品列表信息。同时我们需要查看接口文档,查看是否需要使用其他参数,我们提前将参数准备好。

首先熟悉接口文档:获取商品分页列表

参数名称参数说明是否必须limit每页记录数truepage当前页码truecategory1Id一级分类的 Id (从首页导航分类区域点击进入)falsecategory2Id二级分类的 Id (从分类页面点击进入二级分类进入)false

通过接口文档得知,我们需要以上的参数,我们先将参数提前声明,然后在发起请求获取商品列表的数据

实现步骤:

在商品列表的 data 字段中,根据接口文档,定义商品列表接口需要使用的字段在商品列表的 onLoad 钩子函数中接收请求的参数,并将请求参数进行合并

落地代码:

➡️ /modules/goodsModule/pages/list/list.js

Page({ // 页面的初始数据 data: { goodsList: [], // 商品列表数据 isFinish: false, // 判断数据是否加载完毕 + // 接口请求参数 + requestData: { + page: 1, // 页码 + limit: 10, // 每页请求多少条数据 + category1Id: '', // 一级分类 id + category2Id: '' // 二级分类 id + } }, + // 生命周期函数--监听页面加载 + onLoad(options) { + // 接收传递的参数 + Object.assign(this.data.requestData, options) + } })

12345678910111213141516171819202122 04. 商品列表-获取商品列表数据并渲染

思路分析:

在准备商品列表的请求参数以后,

在页面调用 API 函数获取商品列表的数据,在获取到数据以后,使用后端返回的数据对页面进行渲染。

实现步骤:

在 /pages/goods/list/list.js 中导入封装好的获取商品列表的 API 函数页面数据在页面加载的时候进行调用,在 onLoad 钩子函数中调用 reqGoodsList 方法在获取到数据以后,使用后端返回的数据对页面进行渲染

落地代码:

➡️ /modules/goodsModules/pages/list/list.js

+ import { reqGoodsList } from '../../../../../api/good' Page({ // 页面的初始数据 data: { goodsList: [], // 商品列表数据 + total: 0, // 数据总条数 isFinish: false, // 判断数据是否加载完毕 // 接口请求参数 requestData: { page: 1, // 页码 limit: 10, // 每页请求多少条数据 category1Id: '', // 一级分类 id category2Id: '' // 二级分类 id } }, + // 获取商品列表的数据 + async getGoodsList() { + // 调用 API 获取数据 + const { data } = await reqGoodsList(this.data.requestData) + + // 将返回的数据赋值给 data 中的变量 + this.setData({ + goodsList: data.records, + total: data.total + }) + }, // 生命周期函数--监听页面加载 onLoad(options) { // 接收传递的参数 Object.assign(this.data.requestData, options) + // 获取商品列表的数据 + this.getGoodsList() } })

123456789101112131415161718192021222324252627282930313233343536373839

➡️ /modules/goodsModule/pages/list/list.wxml

<view class="container"> <!-- 商品列表功能 --> + <view class="goods-list" wx:if="{{ goodsList.length }}"> + <block wx:for="{{ goodsList }}" wx:key="id"> + <goods-card goodItem="{{ item }}"></goods-card> + </block> <!-- 数据是否加载完毕 --> <view class="finish" hidden="{{ !isFinish }}">数据加载完毕~~~</view> </view> + <!-- 商品为空的时候展示的结构 --> + <van-empty wx:else description="该分类下暂无商品,去看看其他商品吧~"> + <van-button round type="danger" class="bottom-button" bindtap="gotoBack"> + 查看其他商品 + </van-button> + </van-empty> </view>

1234567891011121314151617181920 05. 商品列表-实现上拉加载更多功能

思路分析:

当用户从下向上滑动屏幕时,需要加载更多的商品数据。

首先需要在 .js 文件中声明 onReachBottom 方法监听用户是否进行了上拉

当用户上拉时,需要对 page 页码进行加 1,代表要请求下一页的数据

当参数发生改变后,需要重新发送请求,拿最新的 page 向服务器发送请求获取数据。

在下一页的商品数据返回以后,将最新的数据和之前的数据进行合并

实现步骤:

list.js 文件中声明 onReachBottom 事件处理函数,监听用户的上拉行为在 onReachBottom 函数中加 page 进行加 1 的操作,同时发送请求获取下一页数据在 getGoodsList 函数中,实现参数的合并

落地代码:

➡️ /modules/goodsModule/pages/list/list.js

import { reqGoodsList } from '../../../api/goods' Page({ // coding... // 获取商品列表的数据 async getGoodsList() { // 调用 API 获取数据 const { data } = await reqGoodsList(this.data.params) // 将返回的数据赋值给 data 中的变量 this.setData({ + goodsList: [...this.data.goodsList, ...data.records], total: data.total }) }, // coding... + // 监听页面的上拉操作 + onReachBottom() { + let { page } = this.data.requestData + + // 页码 + 1 + this.setData({ + requestData: { ...this.data.requestData, page: page + 1 } + }) + + // 重新发送请求 + this.getGoodsList() + } })

1234567891011121314151617181920212223242526272829303132333435 06. 商品列表-判断数据是否加载完毕

思路分析:

上一节我们实现了上拉加载功能。

在这一节,我们需要相关的优化:判断数据是否已经加载完,如果加载已经加载完毕,需要给用户进行提示。

如何判断数据是否加载完成 ❓

可以使用后端返回的 total 和 goodsList 进行对比,如果 total 大于等于 goodsList ,说明商品列表数据没有加载完,可以继续上拉加载更多。

在模板中,我们通过 total 和 goodsList 进行对比,决定是否展示对应的文案

实现步骤:

在数据返回以后,将数据中的 total 赋值给 data 中的变量 total在 onReachBottom 中进行 total 和 goodsList 进行对比模板中使用 total 和 goodsList 进行对比

落地代码:

➡️ /modules/goodsModule/pages/list/list.js

import { reqGoodsList } from '../../../api/goods' Page({ // coding... // 监听页面的上拉操作 onReachBottom() { + // 从 data 中解构数据 + const { total, goodsList, requestData } = this.data + let { page } = requestData + + // 判断数据是否加载完毕 + if (total === goodsList.length) { + // 如果相等,数据数据加载完毕 + // 如果数据加载完毕,需要给用户提示,同时不继续加载下一个数据 + this.setData({ + isFinish: true + }) + + return + } // 页码 + 1 this.setData({ requestData: { ...this.data.requestData, page: (page += 1) } }) // 重新发送请求 this.getGoodsList() } })

123456789101112131415161718192021222324252627282930313233 07. 商品列表-节流阀进行列表节流

在用户网速很慢的情况下,如果用户在距离底部来回的进行多次滑动,可能会发送一些无意义的请求、造成请求浪费的情况,因此需要给上拉加载添加节流功能。

我们使用节流阀来给商品列表添加节流功能。

在 data 中定义节流阀状态 isLoading,默认值是 false。

在请求发送之前,将 isLoading 设置为 true,表示请求正在发送。

在请求结束以后,将 isLoading 设置为 false,表示请求已经完成。

在 onReachBottom 事件监听函数中,对 isLoading 进行判断,如果数据正在请求中,不请求下一页的数据。

落地代码:

➡️ /modules/goodsModule/pages/list/list.js

import { reqGoodsList } from '../../../../../api/good' Page({ // 页面的初始数据 data: { goodsList: [], // 商品列表数据 isFinish: false, // 判断数据是否加载完毕 + isLoading: false, // 判断数据是否记载完毕 total: 0, // 列表总数据量 // 接口请求参数 requestData: { page: 1, // 页码 limit: 10, // 每页请求多少条数据 category1Id: '', // 一级分类 id category2Id: '' // 二级分类 id } }, // 获取商品列表的数据 async getGoodsList() { + // 数据真正请求中 + this.data.isLoading = true // 调用 API 获取数据 const { data } = await reqGoodsList(this.data.requestData) + // 数据加载完毕 + this.data.isLoading = false // 将返回的数据赋值给 data 中的变量 this.setData({ goodsList: [...this.data.goodsList, ...data.records], total: data.total }) }, // 监听页面的上拉操作 onReachBottom() { // 从 data 中解构数据 const { total, goodsList, requestData, isLoading } = this.data let { page } = requestData + // 判断是否加载完毕,如果 isLoading 等于 true + // 说明数据还没有加载完毕,不加载下一页数据 + if (isLoading) return // 判断数据是否加载完毕 // coding... } })

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 08. 商品列表-实现下拉刷新功能

下拉刷新是小程序中常见的一种刷新方式,当用户下拉页面时,页面会自动刷新,以便用户获取最新的内容。

小程序中实现上拉加载更多的方式:

在页面.json 中开启允许下拉,同时可以配置 窗口、loading 样式等

在页面.js 中定义 onPullDownRefresh 事件监听用户下拉刷新

落地代码:

➡️ /modules/goodsModule/pages/list/list.json

{ "usingComponents": { "goods-card": "/components/goods-card/goods-card" }, "navigationBarTitleText": "商品列表", "enablePullDownRefresh": true, "backgroundColor": "#f7f4f8", "backgroundTextStyle": "dark" } 1234567891011

➡️ /modules/goodsModule/pages/list/list.js

// 监听页面的下拉刷新 onPullDownRefresh() { // 将数据进行重置 this.setData({ goodsList: [], total: 0, isFinish: false, requestData: { ...this.data.requestData, page: 1 } }) // 重新获取列表数据 this.getGoodsList() } 12345678910111213 09. 商品详情-获取并渲染商品详情

思路分析:

点击首页轮播图以及点击商品列表商品的时候,需要跳转到商品详情页面

在跳转时将商品的id 传递到了商品详情页面,只需要使用 id 向后端服务器请求数据,获取对应商品的详情数据

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

实现步骤:

在 /pages/goods/detail/detail.js 中导入封装好的获取商品列表的 API 函数页面数据在页面加载的时候进行调用,在 onLoad 钩子函数中调用 reqGoodsInfo 方法在获取到数据以后,使用后端返回的数据对页面进行渲染

落地代码:

➡️ /modules/goodsModule/pages/detail/detail.js

+ import { reqGoodsInfo } from '../../../api/goods' Page({ // 页面的初始数据 data: { goodsInfo: {}, // 商品详情 show: false, // 控制加入购物车和立即购买弹框的显示 count: 1, // 商品购买数量,默认是 1 blessing: '' // 祝福语 }, + // 获取商品的详情 + async getGoodsInfo() { + // 调用接口、传入参数、获取商品详情 + const { data: goodsInfo } = await reqGoodsInfo(this.goodsId) + + // 将商品详情数据赋值给 data 中的变量 + this.setData({ + goodsInfo + }) + }, + // 生命周期函数--监听页面加载 + onLoad(options) { + // 将商品 id 挂载到页面实例上 + this.goodsId = options.goodsId ? options.goodsId : '' + + // 获取商品详情的数据 + this.getGoodsInfo() + } // coding... })

12345678910111213141516171819202122232425262728293031323334

➡️ /modules/goodsModule/pages/detail/detail.html

<view class="container goods-detail"> <!-- 商品大图 --> <view class="banner-img"> + <image class="img" src="{{ goodsInfo.imageUrl }}" /> </view> <!-- 商品的基本信息 --> <view class="content"> <view class="price"> + <view class="price-num">¥{{ goodsInfo.price }}</view> + <view class="price-origin-num">¥{{ goodsInfo.marketPrice }}</view> </view> + <view class="title">{{ goodsInfo.name }}</view> + <view class="desc">{{ goodsInfo.material }}</view> </view> <!-- 商品的详细信息 --> <view class="detail"> <image + wx:for="{{ goodsInfo.detailList}}" + wx:key="index" + src="{{ item }}" class="img" mode="widthFix" /> </view> <!-- 商品的底部商品导航 --> <van-goods-action> <!-- 代码略... --> </van-goods-action> <!-- 加入购物车、立即购买弹框 --> <!-- show 控制弹框的隐藏和展示 --> <!-- bind:close 点击关闭弹框时触发的回调 --> <van-action-sheet show="{{ show }}" bind:close="onClose"> <view class="sheet-wrapper"> <view class="goods-item"> <!-- 需要购买的商品图片 --> <view class="mid"> + <image class="img" src="{{ goodsInfo.imageUrl }}" /> </view> <!-- 商品基本信息 --> <view class="right"> <!-- 商品名字 --> + <view class="title"> {{ goodsInfo.name }} </view> <!-- 商品价格 --> <view class="buy"> <view class="price"> <view class="symbol">¥</view> + <view class="num">{{ goodsInfo.price }}</view> </view> <!-- 购买数量弹框 --> <view class="buy-btn"> <!-- Stepper 步进器,由增加按钮、减少按钮和输入框组成,控制购买数量 --> <van-stepper value="{{ count }}" bind:change="onChangeGoodsCount" /> </view> </view> </view> </view> <!-- 祝福语输入框 --> <view class="time-wraper"> <!-- 代码略... --> </view> <!-- 取消、确定弹框 --> <view class="sheet-footer-btn"> <van-button block type="primary" round> 确定 </van-button> </view> </view> </van-action-sheet> </view>

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 10. 商品详情-详情图片预览功能

思路分析:

当点击商品的图片时,需要将图片进行全屏预览

如果想实现该功能,需要使用小程序提供的 API:wx.previewImage(),用来在新页面中全屏预览图片。预览的过程中用户可以进行保存图片、发送给朋友等操作。语法如下:

wx.previewImage({ current: '', // 当前显示图片的 http 链接 urls: [] // 需要预览的图片 http 链接列表 }) 1234

实现步骤:

给展示大图的 image 组件绑定点击事件,同时通过自定义属性的方式,传递当前需要显示的图片http 链接同时商品详情的数组数据传递给 urls 数组即可

落地代码:

➡️ /pages/goods/detail/detail.html

<!-- 商品大图 --> <view class="banner-img"> <image class="img" src="{{ goodsInfo.imageUrl }}" bindtap="previewImg" /> </view> 12345678

➡️ /pages/goods/detail/detail.js

// 预览商品图片 previewImg() { // 调用预览图片的 API wx.previewImage({ urls: this.data.goodsInfo.detailList }) } 1234567 优化:配置 @ 路径别名优化访问路径

在对小程序进行分包时,如果访问小程序根目录下的文件,那么访问的路径就会很长。

在 Vue 中,可以使用 @ 符号指向源码目录,简化路径,小程序也给提供了配置的方式。

在小程序中可以在 app.json 中使用 resolveAlias 配置项用来自定义模块路径的映射规则。

官方文档: resolveAlias

{ "resolveAlias": { "@/*": "/*" } } 12345

:注意事项:

resolveAlias 进行的是路径匹配,其中的 key 和 value 须以 /* 结尾

如果在 project.config.json 中指定了 miniprogramRoot,则 /* 指代的根目录是 miniprogramRoot 对应的路径,而不是开发者工具项目的根目录

相关知识

微信小程序识别花草方法步骤 微信小程序怎么识别花草
三明大田花店微信小程序怎么做?
鲜花店微信小程序制作方法教程
鲜花花店微信小程序—鲜花预定
【网站项目】鲜花销售微信小程序
同城鲜花配送微信小程序云开发解决方案
基于微信小程序的校园鲜花销售系统
【微信小程序开发实战项目】——如何制作一个属于自己的花店微信小程序(2)
微信小程序 通过data
微信小程序之植物识别demo(百度开发接口)

网址: 微信小程序 https://www.huajiangbk.com/newsview491793.html

所属分类:花卉
上一篇: 烟标上的名花欣赏
下一篇: 选择好花泥的四点建议

推荐分享