行业动态
微信小程序购物商城项目记录:三、home首页
2024-04-15

#头条创作挑战赛#

三、home 首页

### 3.1 创建 home 分支

运行如下的命令,基于 master 分支在本地创建 home 子分支,用来开发和 home 首页相关的功能:

git checkout -b home

3.2 配置网络请求

由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request()API 功能较为简单,不支持拦截器

等全局定制的功能。因此,建议在 uni-app 项目中使用 @

escook/request-miniprogram 第三方包发起网络数据请求

3.2.1 安装 @escook/request-miniprogram

在终端通过如下命令安装:

npm install @escook/request-miniprogram

安装成功后,根目录会自动出现如下目录:

3.2.1 配置网络请求

在项目的 main.js 入口文件中,进行如下配置:

// 导入 $http 对象 import { $http } from @escook/request-miniprogram // 将$http挂在到uni顶级对象之上,方便全局调用 uni.$http = $http // 配置请求根路径 $http.baseUrl = https://www.uinav.com // 请求开始前做一些事情 $http.beforeRequest = function(options) { uni.showLoading({ title: 数据加载中... // 展示loading效果 }) } // 请求完成之后做一些事情 $http.afterRequest = function(options) { uni.hideLoading() // 隐藏loading效果 }

3.3 轮播图区域

3.3.1 请求轮播图的数据

1. 实现步骤

在 data中定义轮播图的数组在 onLoad生命周期函数中调用获取轮播图数据的方法在 methods中定义获取轮播图数据的方法

2. 示例

export default { /** * 初始化数据 * */ data() { return { // 1. 轮播图的数据列表,默认为空数组 swiperList: [], } }, onLoad() { // 2. 在小程序页面钢价在的时候,调用获取轮播图数据的方法 this.getSwiperList() }, methods: { // 3. 获取轮播图数据的方法 async getSwiperList() { // 3.1 发起请求 const { data: res } = await uni.$http.get(/api/public/v1/home/swiperdata) // 3.2 请求失败时执行 if (res.meta.status !== 200) { return uni.showToast({ title: 数据请求失败!, duration: 1500, icon: none, }) } // 3.3 请求成功时为 data 中的数据赋值 this.swiperList = res.message } } }

获取到的数据格式示例如下:

{ "message": [ { "image_src": "https://api-hmugo-web.itheima.net/pyg/banner1.png", "open_type": "navigate", "goods_id": 129, "navigator_url": "/pages/goods_detail/index?goods_id=129" } ], "meta": { "msg": "获取成功", "status": 200 } }

参数说明如下:

参数名

类型

说明

image_src

string

图片路径

open_type

string

打开方式

goods_id

number

商品id

navigator_url

string

导航链接

3.3.2 渲染轮播图的 UI 结构

1. 渲染 UI 结构

<template> <view> <!-- 轮播图区域 --> <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" :circular="true"> <!-- 循环渲染轮播图的 item 项 --> <swiper-item v-for="(item, index) in swiperList" :key="index"> <view class="swiper-item"> <!-- 动态绑定图片的src属性 --> <image :src="item.image_src"></image> </view> </swiper-item> </swiper> </view> </template>

2. 美化 UI 结构

<style lang="scss"> swiper { height: 340rpx; .swiper-item { width: 100%; height: 100%; } } </style>

测试效果如下:

3.3.3 配置小程序分包

分包可以减少小程序首次启动时的加载时间

项目中,将 tabBar相关的 4 个页面放在主包,其他页面(如:商品详情页、商品列表页)放在分包

在 uni-app 项目中,配置分包的步骤如下:

在项目根目录中,创建分包的根目录,命名为 subpkg在 pages.json 中,和 pages节点平级的位置声明 subPackages节点,用来定义分包相关的结构:

{

"subPackages"

: [{

"root": "subpkg"

,

"pages"

: []

}]

}
在 subpkg目录上新建页面

3.3.4 点击轮播图跳转到商品详情页

将 <swiper-item></swiper-item>节点内的view组件,改造为navigator导航组件,并动态绑定url属性的值:

原先的 UI 结构: </swiper-item> 改造之后的 UI 结构: </swiper-item> 在 goods_detail.vue 文件中,编写具体的逻辑:展示传入的商品信息

获取到 goods_id = {{goods_id}} 的商品

export default {

data() {

return {

goods_id: Number,

image_src: String

};

},

// options为进入页面时传入的所有参数的对象

onLoad(options) {

console.log(options)

this.goods_id = options.goods_id

console.log(this.goods_id)

this.image_src = options.image_src

console.log(this.image_src)

}

}

</script>
示例结果如下:

3.3.5 封装 uni.$showMsg()

当数据请求失败之后,经常需要调用 uni.showToast({ /* 配置对象 */ }) 方法来提示用户。此时可以在全局封装一个 uni.$showMsg() 方法,来简化 uni.showToast() 方法的调用

具体实现步骤如下:

在 main.js 中,为 uni对象挂在自定义的 $showMsg() 方法:

/**

* 封装展示消息提示的方法

*/

uni.$showMsg = function(title = 数据加载失败!, duration = 1500) {

uni.showToast({

title,

duration,

icon: none,

})

}
更改原先请求失败时提示消息的调用:

// 3. 获取轮播图数据的方法

async getSwiperList() {

// 3.1 发起请求

const { data: res } = await uni.$http.get(/api/public/v1/home/swiperdata)

// 3.2 请求失败时执行

if (res.meta.status !== 200) return uni.$showMsg()

// 3.3 请求成功时为 data 中的数据赋值

this.swiperList = res.message

}

3.4 分类导航区域

3.4.1 获取分类导航的数据

1. 实现思路

在 data中定义轮播图的数组在 onLoad生命周期函数中调用获取数据的方法在 methods中定义获取数据的方法

2. 示例

<script> export default { data() { return { // 1. 分类导航的数据列表 navList: [], }; }, onLoad() { // 2. 在 onLoad 中调用获取数据的方法 this.getNavList() }, methods: { // 3. 在 methods 中定义获取数据的方法 async getNavList() { const { data: res } = await uni.$http.get(/api/public/v1/home/catitems) if (res.meta.status !== 200) return uni.$showMsg() this.navList = res.message } } } </script>

3. 获取到的数据如下所示:

{ "message": [ { "name": "分类", "image_src": "https://api-hmugo-web.itheima.net/pyg/icon_index_nav_4@2x.png", "open_type": "switchTab", "navigator_url": "/pages/category/index" }, { "name": "秒杀拍", "image_src": "https://api-hmugo-web.itheima.net/pyg/icon_index_nav_3@2x.png" }, { "name": "超市购", "image_src": "https://api-hmugo-web.itheima.net/pyg/icon_index_nav_2@2x.png" }, { "name": "母婴品", "image_src": "https://api-hmugo-web.itheima.net/pyg/icon_index_nav_1@2x.png" } ], "meta": { "msg": "获取成功", "status": 200 } }

返回参数说明 :

参数名

类型

说明

name

string

标题名称

image_src

string

图片路径

3.4.2 渲染分类导航的 UI 结构

定义如下的 UI 结构 </template> 通过如下的样式美化页面结构:

.nav-list {

display: flex;

justify-content: space-around;

margin: 15px 0;

.nav-img {

width: 128rpx;

height: 140rpx;

}

}

</style>
测试效果如下:

3.4.3 点击**项,切换到分类页面

为 nav-item 绑定点击事件处理函数: </view> 定义 nacClickHandler事件处理函数:

export default {

methods: {

// nav-item 项被点击时的事件处理函数

navClickHandler(item) {

// 判断点击的是哪个 nav

if (item.name == 分类) {

uni.switchTab({

url: /pages/cate/cate

})

}

}

}

}

</script>

4.5 楼层区域

4.5.1 获取楼层数据

1. 实现思路

在 data中定义轮播图的数组在 onLoad生命周期函数中调用获取数据的方法在 methods中定义获取数据的方法

2. 示例

<script> export default { data() { return { // 1. 楼层的数据列表 floorList: [], }; }, onLoad() { // 2. 调用获取楼层数据的方法 this.getFloorList() }, methods: { // async getFloorList() { const { data: res } = await uni.$http.get(/api/public/v1/home/floordata) if (res.meta.status !== 200) uni.$showMsg() this.floorList = res.message } } } </script>

3. 获取到的数据示例

{ "message": [ { "floor_title": { "name": "时尚女装", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor01_title.png" }, "product_list": [ { "name": "优质服饰", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor01_1@2x.png", "image_width": "232", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=服饰" }, { "name": "春季热门", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor01_2@2x.png", "image_width": "233", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=热" }, { "name": "爆款清仓", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor01_3@2x.png", "image_width": "233", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=爆款" }, { "name": "倒春寒", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor01_4@2x.png", "image_width": "233", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=春季" }, { "name": "怦然心动", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor01_5@2x.png", "image_width": "233", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=心动" } ] }, { "floor_title": { "name": "户外活动", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor02_title.png" }, "product_list": [ { "name": "勇往直前", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor02_1@2x.png", "image_width": "232", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=户外" }, { "name": "户外登山包", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor02_2@2x.png", "image_width": "273", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=登山包" }, { "name": "超强手套", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor02_3@2x.png", "image_width": "193", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=手套" }, { "name": "户外运动鞋", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor02_4@2x.png", "image_width": "193", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=运动鞋" }, { "name": "冲锋衣系列", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor02_5@2x.png", "image_width": "273", "open_type": "navigate", "navigator_url": "/pages/goods_list/index?query=冲锋衣" } ] }, { "floor_title": { "name": "箱包配饰", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor03_title.png" }, "product_list": [ { "name": "清新气质", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor03_1@2x.png", "image_width": "232", "open_type": "navigate", "navigator_url": "/pages/goods_list?query=饰品" }, { "name": "复古胸针", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor03_2@2x.png", "image_width": "263", "open_type": "navigate", "navigator_url": "/pages/goods_list?query=胸针" }, { "name": "韩版手链", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor03_3@2x.png", "image_width": "203", "open_type": "navigate", "navigator_url": "/pages/goods_list?query=手链" }, { "name": "水晶项链", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor03_4@2x.png", "image_width": "193", "open_type": "navigate", "navigator_url": "/pages/goods_list?query=水晶项链" }, { "name": "情侣表", "image_src": "https://api-hmugo-web.itheima.net/pyg/pic_floor03_5@2x.png", "image_width": "273", "open_type": "navigate", "navigator_url": "/pages/goods_list?query=情侣表" } ] } ], "meta": { "msg": "获取成功", "status": 200 } }

返回参数说明

参数名

类型

说明

floor_title

string

一级分类标题

product_list

array

一级分类内容

name

string

名称

image_src

string

图片路径

image_width

string

图片宽度

open_type

string

打开方式

navigator_url

string

跳转连接

3.5.2 渲染楼层的标题

定义如下的 UI 结构: </template> 美化楼层标题的样式

.floor-title {

height: 60rpx;

width: 100%;

display: flex;

}

</style>

3.5.3 渲染楼层里的图片

定义楼层图片区域的UI结构:

:style="{width: item.product_list[0].image_width + rpx}" mode="widthFix">

</template>
美化楼层图片区域的样式:

.floor-title {

height: 60rpx;

width: 100%;

display: flex;

}

.right-img-box {

display: flex;

flex-wrap: wrap;

justify-content: space-around;

}

.floor-img-box {

display: flex;

padding-left: 10rpx;

}

</style>
完整的测试效果如下:

3.5.4 点击楼层图片跳转到商品列表项

在 subpkg 分包中,新建 goods_list 页面楼层数据请求成功之后,通过双层 forEach 循环,处理 URL 地址:

export default {

methods: {

// 3. 获取楼层列表数据

async getFloorList() {

const {

data: res

} = await uni.$http.get(/api/public/v1/home/floordata)

if (res.meta.status !== 200) uni.$showMsg()

// 通过双层 forEach 循环,处理 URL 地址

res.message.forEach(floor => {

floor.product_list.forEach(prod => {

prod.url = /subpkg/goods_list/goods_list? + prod.navigator_url.split(?)[

1]

})

})

this.floorList = res.message

}

}

}

</script>
将图片外层的 view 组件,改造为 navigator 组件,并动态绑定 url 属性的值:

:style="{width: item.product_list[0].image_width + rpx}" mode="widthFix">

:url="item2.url">

</template>
测试效果如下:点击任意一个图片之后:

3.6 分支的合并与提交

将本地的home分支进行本地的commit提交:

git add .

git commit -m "完成了home首页的开发"
将本地的home分支推送到远程仓库进行保存:git push -u origin home将本地的 home 分支合并到本地的 master 分支:

git checkout master

git merge home
删除本地的 home 分支git branch -d home


1063568276