#头条创作挑战赛#
三、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