一、项目基本结构
(一)tabbar页面
首页
分类
购物车
我的(用户中心)
(二)非tabbar页面
搜索
商品列表
商品详情
微信支付
结构解析:
1. 构建一个小程序,需要先将小程序的页面结构分类、理清。
现大多数小程序页面结构分为tabbar页面和非tabbar页面。tabbar页面作为小程序的主体框架,所以应该先搭建好tabbar页面,非tabbar页面在此框架上运行。
2. 由于存在tabbar页面和非tabbar页面,因此将小程序项目分为主包和分包
主包:小程序启动页或tabbar页面以及公共资源
分包:非tabbar页面和私有资源
普通分包页面:先下载主包,再跳转至普通分包运行普通分包的页面
独立分包页面:不依赖于主包,可自己独立运行(配置时加上:"independent" : true)
配置pages.json
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "优购商城"
}
},
{
"path": "pages/category/category",
"style": {
"navigationBarTitleText": "分类",
"enablePullDownRefresh": false
}
},
{
"path": "pages/cart/cart",
"style": {
"navigationBarTitleText": "购物车",
"enablePullDownRefresh": false
}
}, {
"path": "pages/user/user",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false
}
}
],
分包
//分包
"subPackages": [{
"root": "subpkg1",
"pages": [{
"path": "goods-list/goods-list",
"style": {
"navigationBarTitleText": "商品列表",
"backgroundColor": "#cecece",
"onReachBottomDistance": 100,
"enablePullDownRefresh": true
}
},
配置pages.json
"preloadRule": { // preloadRule 关键字与pages平级
"pages/index": { // pages/index 触发预下载的路径
"network": "all", // network 表示在指定网络模式下进行预下载 可选all/wifi
"packages": ["package1"] // packages 预下载哪个分包 ["分包root或name"]
},
"sub1/index": {
"packages": ["package2", "package3"]
},
3.tabbar徽标的配置
以此项目为例:cart页面需要右上角徽标,且切换至其他tabbar页面时,cart页面的徽标也要显示(当数值为零时移除徽标)
当多个页面都有相同业务逻辑时,封装一个mixins(js),然后引入至各个页面使用
注意事项
配置pages.json
"mp-weixin" : {
/* 小程序特有相关 */
"setting" : {
/*其他代码*/
"checkSiteMap":false
},
},
4.搭建页面,组件以及数据获取
1.使用<scroll-view>:
1)指定划定方向:scroll-y
2)给定一个宽定或高定:onload()时,获取可使用窗口高度
二,页面搭建
1.在分页pages下的index.vue得到以下
<template>
<view class="index">
<!-- 搜索 -->
<xd-header></xd-header>
<!-- 轮播图 -->
<view class="index-swiper">
<swiper indicator-dots="true" autoplay="true" interval="3000" duration="1000">
<swiper-item v-for="(item, index) in swiperList" :key="index">
<image :src="item.image_src" mode="widthFix"></image>
</swiper-item>
</swiper>
</view>
<!-- 导航 -->
<view class="index-cate">
<view class="image-box" v-for="(item,index) in navList" :key="index">
<image :src="item.image_src" mode="widthFix"></image>
</view>
</view>
<!-- 楼层数据 -->
<view class="index-floor">
<view class="floor-group" v-for="(item,index) in floorList" :key="index">
<view class="floor-title">
<image :src="item.floor_title.image_src" mode="widthFix"></image>
</view>
<view class="floor-list">
<view class="image-box" v-for="(item2,index2) in item.product_list">
<image :src="item2.image_src" mode="scaleToFill"></image>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
swiperList: [],
navList: [],
floorList: []
}
},
onLoad() {
this.getSwiperList();
this.getNavList();
this.getFloorList();
},
methods: {
// 未封装
// getSwiperList(){
// uni.request({
// url:"https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata",
// success:(res)=>{
// console.log(res);
// this.swiperList=res.data.message;
// }
// })
// },
// 封装
// getSwiperList(){
// this.$Https({
// url:'/home/swiperdata'
// }).then((res)=>{
// console.log(res);
// this.swiperList = res.message;
// })
// },
// asyc 异步 await等待
async getSwiperList() {
// await只能在async标识的函数内使用 await会堵塞后续代码运行
const res = await this.$Https({
url: "/home/swiperdata"
});
console.log(res);
this.swiperList = res.message;
},
// getNavList(){
// uni.request({
// url:"https://api-hmugo-web.itheima.net/api/public/v1/home/catitems",
// success:(res)=>{
// console.log(res);
// this.navList=res.data.message;
// }
// })
// }
async getNavList() {
const res = await this.$Https({
url: '/home/catitems'
});
console.log(res);
this.navList = res.message;
},
// 获取楼层数据
async getFloorList() {
const res = await this.$Https({
url: '/home/floordata'
});
console.log(res);
this.floorList = res.message;
}
}
}
</script>
<style lang="scss">
page {
padding-top: 90rpx;
}
.index-swiper {
swiper {
width: 750rpx;
height: 340rpx;
image {
width: 100%;
}
}
}
.index-cate {
width: 750rpx;
display: flex;
.image-box {
flex: 1;
padding: 20rpx;
image {
width: 100%;
}
}
}
.index-floor {
width: 750rpx;
.floor-title {
image {
width: 100%;
}
}
.floor-list {
padding: 15rpx;
.image-box {
width: 240rpx;
height: calc(240rpx * 386 / 232);
float: left;
&:nth-last-child(-n+4) {
height: calc(240rpx * 386 / 232 / 2);
border-left: 10rpx solid #ffffff;
}
&:nth-child(2),
&:nth-child(3) {
border-bottom: 10rpx solid #ffffff;
}
image {
width: 100%;
height: 100%;
}
}
}
}
</style>
在componets下创建header.vue得到
<template>
<view class="header">
<navigator class="search" url="../category/category" open-type="switchTab">
<text class="iconfont icon-sousuo"></text>
<text>搜索</text>
</navigator>
</view>
</template>
<script>
export default {
name:"xd-header",
data() {
return {
};
}
}
</script>
<style lang="scss">
.header{
width: 750rpx;
height: 90rpx;
background-color: #c00053;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
top: var(--window-top);
z-index: 10;
}
.search{
width: 720rpx;
height: 60rpx;
background-color: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
</style>
2.在pages下创建category
<template>
<view>
<xd-header></xd-header>
<view class="index-cate">
<scroll-view class="left-menu" scroll-y="true">
<view class="category" :class="index===currentIndex?'active':''" v-for="(item,index) in leftMenuList"
:key="