3. 首页
展示:
接口描述:
- 轮播图
请求URL:
https://api-ugo-web.itheima.net/api/public/v1/home/swiperdata
请求方式:
- GET
参数: 无
返回示例
{
"message": [
{
"image_src": "https://api-ugo-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 | 导航链接 |
接口描述:
- 导航菜单
请求URL:
https://api-ugo-web.itheima.net/api/public/v1/home/catitems
请求方式:
- GET
参数: 无
返回示例
{
"message": [
{
"name": "分类",
"image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_4@2x.png",
"open_type": "switchTab",
"navigator_url": "/pages/category/index"
},
{
"name": "秒杀拍",
"image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_3@2x.png"
},
{
"name": "超市购",
"image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_2@2x.png"
},
{
"name": "母婴品",
"image_src": "https://api-ugo-web.itheima.net/pyg/icon_index_nav_1@2x.png"
}
],
"meta": {
"msg": "获取成功",
"status": 200
}
}
返回参数说明
参数名 | 类型 | 说明 |
---|---|---|
name | string | 标题名称 |
image_src | string | 图片路径 |
简要描述:
- 楼层
请求URL:
https://api-ugo-web.itheima.net/api/public/v1/home/floordata
请求方式:
- GET
参数: 无
返回示例
{
"message": [
{
"floor_title": {
"name": "时尚女装",
"image_src": "https://api-ugo-web.itheima.net/pyg/pic_floor01_title.png"
},
"product_list": [
{
"name": "优质服饰",
"image_src": "https://api-ugo-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-ugo-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-ugo-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-ugo-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-ugo-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-ugo-web.itheima.net/pyg/pic_floor02_title.png"
},
"product_list": [
{
"name": "勇往直前",
"image_src": "https://api-ugo-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-ugo-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-ugo-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-ugo-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-ugo-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-ugo-web.itheima.net/pyg/pic_floor03_title.png"
},
"product_list": [
{
"name": "清新气质",
"image_src": "https://api-ugo-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-ugo-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-ugo-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-ugo-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-ugo-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.1 创建 home 分支
运行如下的命令,基于 master
分支在本地创建 home
子分支,用来开发和 home
首页相关的功能:
git checkout -b home
3.2 配置网络请求
由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request() API 功能较为简单,不支持拦截器等全局定制的功能。因此,建议在 uni-app 项目中使用 @escook/request-miniprogram
第三方包发起网络数据请求。
请参考 @escook/request-miniprogram 的官方文档进行安装、配置、使用官方文档:https://www.npmjs.com/package/@escook/request-miniprogram
最终,在项目的 main.js
入口文件中,通过如下的方式进行配置:
import { $http } from '@escook/request-miniprogram'
uni.$http = $http
// 配置请求根路径
$http.baseUrl = 'https://api-ugo-web.itheima.net'
// 请求开始之前做一些事情
$http.beforeRequest = function (options) {
uni.showLoading({
title: '数据加载中...',
})
}
// 请求完成之后做一些事情
$http.afterRequest = function () {
uni.hideLoading()
}
3.3 轮播图区域
3.3.1 请求轮播图的数据
实现步骤:
- 在
data
中定义轮播图的数组 - 在
onLoad
生命周期函数中调用获取轮播图数据的方法 - 在
methods
中定义获取轮播图数据的方法
示例代码:
//home.vue
export default {
data() {
return {
//存放轮播图数据
swiperList:[]
};
},
onLoad(){
//在小程序页面刚加载的时候,调用获取轮播图数据的方法
this.getSwiperList()
},
methods:{
//获取轮播图数据
async getSwiperList(){
//发起请求,从返回的数据中结构出data并起个res的别名
const {data:res} = await uni.$http.get('/api/public/v1/home/swiperdata')
//请求失败
if(res.meta.status !==200){
return uni.showToast({
title:'数据请求失败!',
duration:1500,
icon:'none',
})
}
//请求成功
this.swiperList=res.message
}
}
}
如果你在使用接口时报了如下错误:
net::ERR_PROXY_CONNECTION_FAILED(env: Windows,mp,1.05.2201240; lib: 2.24.0)解决方法: 关掉重启微信开发者工具 。 如果还不行就关机重启,再不行就试试关掉你的Http代理。
出错问题估计是某些进程没有结束导致的。
3.3.2 渲染轮播图的 UI 结构
渲染 UI 结构:
<template>
<!-- home.vue -->
<view>
<!-- 轮播图区域 -->
<!-- indicator-dots:是否显示面板指示点
autoplay:是否自动切换
interval:自动切换时间间隔
duration:滑动动画时长
circular:是否采用衔接滑动
更多配置查看微信小程序开发文档
-->
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" :circular="true">
<!-- 循环渲染item项 -->
<swiper-item v-for="(item,i) in swiperList" :key="i">
<view class="swiper_item">
<!-- 动态绑定图片的src属性-->
<image :src="item.image_src" ></image>
</view>
</swiper-item>
</swiper>
</view>
</template>
美化 UI 结构:
<style lang="scss">
// home.vue
swiper{
height: 330rpx;
.swiper_item,image {
height:100% ;
width: 100%;
}
}
</style>
3.3.3 配置小程序分包
分包可以减少小程序首次启动时的加载时间
为此,我们在项目中,把 tabBar
相关的 4 个页面放到主包中,其它页面(例如:商品详情页、商品列表页)放到分包中。在 uni-app
项目中,配置分包的步骤如下:
- 在项目根目录中,创建分包的根目录,命名为
subpkg
在
pages.json
中,和pages
节点平级的位置声明subPackages
节点,用来定义分包相关的结构:{ "pages": [ { "path": "pages/home/home", "style": {} }, { "path": "pages/cate/cate", "style": {} }, { "path": "pages/cart/cart", "style": {} }, { "path": "pages/my/my", "style": {} } ], "subPackages": [ { "root": "subpkg", "pages": [] } ] }
- 在
subpkg
目录上鼠标右键,点击新建页面
选项,并填写页面的相关信息:
3.3.4 点击轮播图跳转到商品详情页面
将 <swiper-item></swiper-item>
节点内的 view
组件,改造为 navigator
导航组件,并动态绑定 url 属性
的值。
改造之前的 UI 结构:
<swiper-item v-for="(item, i) in swiperList" :key="i"> <view class="swiper-item"> <!-- 动态绑定图片的 src 属性 --> <image :src="item.image_src"></image> </view> </swiper-item>
改造之后的 UI 结构:
<swiper-item v-for="(item, i) in swiperList" :key="i"> <navigator class="swiper-item" :url="'/subpkg/goods_detail/goods_detail?goods_id=' + item.goods_id"> <!-- 动态绑定图片的 src 属性 --> <image :src="item.image_src"></image> </navigator> </swiper-item>
3.3.5 封装 uni.$showMsg() 方法
当数据请求失败之后,经常需要调用 uni.showToast({ /* 配置对象 */ })
方法来提示用户。此时,可以在全局封装一个 uni.$showMsg()
方法,来简化 uni.showToast()
方法的调用。具体的改造步骤如下:
在
main.js
中,为uni
对象挂载自定义的$showMsg()
方法:// 封装的展示消息提示的方法 //接收两个参数,一个title(默认值为数据加载失败),一个duration(持续时间,默认为1500ms) uni.$showMsg = function (title = '数据加载失败!',duration=1500){ uni.showToast({ title, duration, icon:'none', }) }
今后,在需要提示消息的时候,直接调用
uni.$showMsg()
方法即可://请求失败 if(res.meta.status !==200) return uni.$showMsg()
3.4 分类导航区域
3.4.1 获取分类导航的数据
实现思路:
- 定义
data
数据 - 在
onLoad
中调用获取数据的方法 - 在
methods
中定义获取数据的方法
示例代码如下:
// home.vue
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
},
},
}
3.4.2 渲染分类导航的 UI 结构
定义如下的 UI 结构:
<!-- home.vue -->
<!-- 分类导航区域 -->
<view class="nav-list">
<view class="nav-item" v-for="(item, i) in navList" :key="i">
<image :src="item.image_src" class="nav-img"></image>
</view>
</view>
通过如下的样式美化页面结构:
// home.vue
.nav-list {
display: flex;
justify-content: space-around;
margin: 15px 0;
.nav-img {
width: 128rpx;
height: 140rpx;
}
}
3.4.3 点击第一项,切换到分类页面
为
nav-item
绑定点击事件处理函数:<!-- 分类导航区域 --> <view class="nav-list"> <view class="nav-item" v-for="(item, i) in navList" :key="i" @click="navClickHandler(item)"> <image :src="item.image_src" class="nav-img"></image> </view> </view>
定义
navClickHandler
事件处理函数:// nav-item 项被点击时候的事件处理函数 navClickHandler(item) { // 判断点击的是哪个 nav if (item.name === '分类') { uni.switchTab({ url: '/pages/cate/cate' }) } }
3.5 楼层区域
3.5.1 获取楼层数据
实现思路:
- 定义
data
数据 - 在
onLoad
中调用获取数据的方法 - 在
methods
中定义获取数据的方法
示例代码如下:
export default {
data() {
return {
// 1. 楼层的数据列表
floorList: [],
}
},
onLoad() {
// 2. 在 onLoad 中调用获取楼层数据的方法
this.getFloorList()
},
methods: {
// 3. 定义获取楼层列表数据的方法
async getFloorList() {
const { data: res } = await uni.$http.get('/api/public/v1/home/floordata')
if (res.meta.status !== 200) return uni.$showMsg()
this.floorList = res.message
},
},
}
3.5.2 渲染楼层的内容
定义如下的 UI 结构:
<view class="floor-list">
<view class="floor-item" v-for="(item,i) in floorList" :key="i">
<!-- 楼层标题 -->
<image :src="item.floor_title.image_src" class="floor-title"></image>
<!-- 楼层图片区域 -->
<view class="floor-img-box">
<!-- 左侧大图片盒子 -->
<view class="left-img-box">
<!-- widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 -->
<image :src="item.product_list[0].image_src" :style="{width:item.product_list[0].image_width+'rpx'}" mode="widthFix"></image>
</view>
<!-- 右侧4个小图片盒子 -->
<view class="right-img-box">
<view class="right-img-item" v-for="(item2,i2) in item.product_list" :key="i2" v-if="i2 !==0">
<image :src="item2.image_src" mode="widthFix" :style="{width:item2.image_width+'rpx'}"></image>
</view>
</view>
</view>
</view>
</view>
美化楼层的样式:
.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;
}
3.5.3 点击楼层图片跳转到商品列表页
- 在
subpkg
分包中,新建goods_list
页面 楼层数据请求成功之后,通过双层
forEach
循环,处理 URL 地址:// 获取楼层列表数据 async getFloorList() { const { data: res } = await uni.$http.get('/api/public/v1/home/floordata') if (res.meta.status !== 200) return 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 }
把图片外层的
view
组件,改造为navigator
组件,并动态绑定url
属性 的值:<!-- 楼层图片区域 --> <view class="floor-img-box"> <!-- 左侧大图片的盒子 --> <navigator class="left-img-box" :url="item.product_list[0].url"> <image :src="item.product_list[0].image_src" :style="{width: item.product_list[0].image_width + 'rpx'}" mode="widthFix"></image> </navigator> <!-- 右侧 4 个小图片的盒子 --> <view class="right-img-box"> <navigator class="right-img-item" v-for="(item2, i2) in item.product_list" :key="i2" v-if="i2 !== 0" :url="item2.url"> <image :src="item2.image_src" mode="widthFix" :style="{width: item2.image_width + 'rpx'}"></image> </navigator> </view> </view>
3.6 分支的合并与提交
将本地的
home
分支进行本地的commit
提交:切换到home分支
git checkout home
查看当前分支
git branch
git add . git commit -m "完成了 home 首页的开发"
将本地的
home
分支推送到远程仓库进行保存:git push -u origin home
将本地的
home
分支合并到本地的master
分支:git checkout master git merge home
更新主仓库(master):
git push
删除本地的
home
分支:git branch -d home