分包可以减少小程序首次启动时的加载时间
项目中,将 tabBar相关的 4 个页面放在主包,其他页面(如:商品详情页、商品列表页)放在分包
在 uni-app 项目中,配置分包的步骤如下:
- 在项目根目录中,创建分包的根目录,命名为 subpkg
- 在 pages.json 中,和 pages节点平级的位置声明 subPackages节点,用来定义分包相关的结构:
- {
"subPackages": [{
"root": "subpkg",
"pages": []
}]
} - 在 subpkg目录上新建页面
将 <swiper-item></swiper-item>节点内的view组件,改造为navigator导航组件,并动态绑定url属性的值:
- 原先的 UI 结构:
- <swiper-item v-for="(item, index) in swiperList" :key="index">
<view class="swiper-item">
<!-- 动态绑定图片的src属性 -->
<image :src="item.image_src"></image>
</view>
</swiper-item> - 改造之后的 UI 结构:
- <swiper-item v-for="(item, index) in swiperList" :key="index">
<!-- 指定对应的商品页面,传入对应的商品信息 -->
<navigator class="swiper-item" :url="'/subpkg/goods_detail/goods_detail?goods_id=' item.goods_id '&image_src=' item.image_src">
<!-- 动态绑定图片的src属性 -->
<image :src="item.image_src"></image>
</navigator>
</swiper-item> - 在 goods_detail.vue 文件中,编写具体的逻辑:展示传入的商品信息
- <template>
<view>
<view>获取到 goods_id = {{goods_id}} 的商品</view>
<image :src="image_src" mode="scaleToFill" style="width: 100%;"></image>
</view>
</template>
<script>
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> - 示例结果如下:
当数据请求失败之后,经常需要调用 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
}
- 在 data中定义轮播图的数组
- 在 onLoad生命周期函数中调用获取数据的方法
- 在 methods中定义获取数据的方法
<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 | 图片路径 |
- 定义如下的 UI 结构
- <template>
<!-- 分类导航区域 -->
<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>
</template> - 通过如下的样式美化页面结构:
- <style lang="scss">
.nav-list {
display: flex;
justify-content: space-around;
margin: 15px 0;
.nav-img {
width: 128rpx;
height: 140rpx;
}
}
</style> - 测试效果如下:
- 为 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> - 定义 nacClickHandler事件处理函数:
- <script>
export default {
methods: {
// nav-item 项被点击时的事件处理函数
navClickHandler(item) {
// 判断点击的是哪个 nav
if (item.name == '分类') {
uni.switchTab({
url: '/pages/cate/cate'
})
}
}
}
}
</script>
- 在 data中定义轮播图的数组
- 在 onLoad生命周期函数中调用获取数据的方法
- 在 methods中定义获取数据的方法
<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 | 跳转连接 |
- 定义如下的 UI 结构:
- <template>
<!-- 楼层区域 -->
<view class="floor-list">
<!-- 楼层的 item 项 -->
<view class="floor-item" v-for="(item, i) in floorList" :key="i">
<!-- 楼层标题 -->
<image :src="item.floor_title.image_src" class="floor-title"></image>
</view>
</view>
</template> - 美化楼层标题的样式
- <style lang="scss">
.floor-title {
height: 60rpx;
width: 100%;
display: flex;
}
</style>
- 定义楼层图片区域的UI结构:
- <template>
<!-- 楼层区域 -->
<view class="floor-list">
<!-- 楼层的 item 项 -->
<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">
<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>
</template> - 美化楼层图片区域的样式:
- <style lang="scss">
.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> - 完整的测试效果如下: