1. 首页

2. 创建home分支

  1. git checkout -b home

3. 配置网络请求

由于平台的限制,小程序项目中不支持 axios,而且原生的 wx.request() API 功能较为简单,不支持拦截器等全局定制的功能。因此,建议在 uni-app 项目中使用 @escook/request-miniprogram 第三方包发起网络数据请求。

请参考 @escook/request-miniprogram 的官方文档进行安装、配置、使用

官方文档:https://www.npmjs.com/package/@escook/request-miniprogram

在项目目录下初始化npb并安装request-miniprogram

  1. npm init
  2. npm install @escook/request-miniprogram

在main.js中导入模块 并测试拦截器

  1. //导入网络请求的包
  2. import {
  3. $http
  4. } from '@escook/request-miniprogram'
  5. uni.$http = $http
  6. //请求根路径
  7. $http.baseUrl = 'https://www.uinav.com'
  8. //请求拦截器
  9. $http.beforeRequest = function(option) {
  10. uni.showLoading({ //展示加载
  11. title: '数据加载中...'
  12. })
  13. }
  14. //响应拦截器
  15. $http.afterRequest = function(option) {
  16. uni.hideLoading() //关闭加载
  17. }

4. 轮播图

4.1. 请求轮播图的数据

  1. 在 data 中定义轮播图的数组
    1. data() {
    2. return {
    3. //轮播图列表
    4. swiperList: []
    5. };
    6. }
  1. 在 onLoad 生命周期函数中调用获取轮播图数据的方法
    1. onLoad(){
    2. //创建钩子 获取轮播列表
    3. this.getSwioerList()
    4. }
  1. 在manifest.json 将微信小程序的 ES6 转 ES5 开启

  2. 在 methods 中定义获取轮播图数据的方法

    1. methods: {
    2. async getSwioerList() {
    3. const { data: res } = await uni.$http.get('/api/public/v1/home/swiperdata');
    4. // console.log(res)
    5. //请求失败
    6. if (res.meta.status !== 200) {
    7. return uni.showToast({
    8. title:'数据请求失败', // 提示框内容
    9. duration: 1500, //提示框多久消失 毫秒
    10. icon:'none' //提示框图标
    11. });
    12. }
    13. this.swiperList =res.message
    14. // console.log(this.swiperList)
    15. }
    16. }

4.2. 渲染轮播图的UI结构

  1. 在home.js 模块标签中使用 swiper标签展示轮播图
    uni-app 可以使用usw快速生成uni swiper 模块代码
    04. 首页 - 图1

    1. <template>
    2. <view>
    3. <!-- 轮播图 -->
    4. <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
    5. <swiper-item v-for="(item,i) in swiperList" :key="i">
    6. <view class="swiper-item">
    7. <image :src="item.image_src"></image>
    8. </view>
    9. </swiper-item>
    10. </swiper>
    11. </view>
    12. </template>
  1. 轮播图样式 ```scss

    1. <a name="84956930"></a>
    2. ## 4.3. 配置小程序分包
    3. **分包可以减少小程序首次启动时的加载时间**
    4. 1.
    5. 在项目根目录中,创建分包的根目录,命名为 `subpkg`
    6. 2.
    7. 在 `pages.json` 中,和 `pages` 节点平级的位置声明 `subPackages` 节点,用来定义分包相关的结构:
    8. ```json
    9. "subPackages": [
    10. {
    11. "root": "subpkg",
    12. "pages": []
    13. }
    14. ]
    1. subpkg 创建页面 goods_detail 选择subpkg为分包目录
      04. 首页 - 图2

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

    <swiper-item></swiper-item> 节点内的 view 组件,改造为 navigator 导航组件,并动态绑定 url 属性 的值。因为view不能实现跳转

    1. <swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
    2. <swiper-item v-for="(item, i) in swiperList" :key="i">
    3. <navigator class="swiper-item" :url="'/subpkg/goods_detail/goods_detail?goods_id=' + item.goods_id"><image :src="item.image_src"></image></navigator>
    4. </swiper-item>
    5. </swiper>

    4.5. 封装 uni.$showMsg()方法

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

    1. main.js 中,为 uni 对象挂载自定义的 $showMsg() 方法:
      1. //封装提醒框方法
      2. uni.$showMsg = function(title = '数据请求失败',duration = 1500){
      3. uni.showToast({
      4. title,
      5. duration,
      6. icon:'none'
      7. })
      8. }
    1. 在需要提示消息的时候,直接调用 uni.$showMsg() 方法即可
      1. methods: {
      2. async getSwioerList() {
      3. const { data: res } = await uni.$http.get('/api/public/v1/home/swiperdata');
      4. console.log(res)
      5. //请求失败
      6. if (res.meta.status !== 200) {
      7. /* return uni.showToast({
      8. title:'数据请求失败', // 提示框内容
      9. duration: 1500, //提示框多久消失 毫秒
      10. icon:'none' //提示框图标
      11. }); */
      12. return uni.$showMsg()
      13. }
      14. this.swiperList =res.message
      15. uni.$showMsg('数据请求成功!')
      16. console.log(this.swiperList)
      17. }
      18. }

    5. 分类导航区域

    5.1. 获取首页分类选项数据

    1. 在home.vue 定data数据
      1. //分类导航列表
      2. navList:[]
    1. 在onLoad调用获取数据方法
      1. //获取分类导航列表
      2. this.getNavList()
    1. 在 methods 中定义获取数据的方法
      1. //获取分类导航数据
      2. async getNavList() {
      3. const { data: res } = await uni.$http.get('/api/public/v1/home/catitems')
      4. // console.log(res)
      5. if(res.meta.status !== 200){
      6. return uni.$showMsg()
      7. }
      8. uni.$showMsg("获取数据成功")
      9. this.navList = res.message
      10. console.log(this.navList)
      11. }

    5.2. 渲染分类导航UI结构

    1. 在template 中 view 渲染
      1. <!-- 分类导航区 -->
      2. <view class="nav-list">
      3. <view class="nav-item" v-for="(item, i) in navList" :key="i">
      4. <image :src="item.image_src" class="nav-img"></image>
      5. </view>
      6. </view>
    1. 修改样式
      1. .nav-list {
      2. display: flex;
      3. justify-content: space-around;
      4. margin: 15px 0;
      5. .nav-img {
      6. width: 128rpx;
      7. height: 140rpx;
      8. }
      9. }

    5.3. 点击第一项,跳转到分类页面

    1. 给nav-item 绑定点击事件
      1. <view class="nav-item" v-for="(item, i) in navList" :key="i" @click="navClickHandler(item)" >
    1. 定义navClickHandler方法
      1. //根据用户点击的分类导航跳转到对应的页面
      2. navClickHandler(item){
      3. if(item.name === '分类'){ //判断是否是分类导航图标
      4. uni.switchTab({
      5. url:'/pages/cate/cate' //跳转到指定页面
      6. })
      7. }
      8. }

    5.4. 楼层区域

    5.4.1. 获取楼层数据

    1. 定义data数据
      1. //楼层数据
      2. floorList: []
    1. 在创建钩子 调用方法
      1. //获取楼层数据
      2. this.getFloorList()
    1. 定义方法
      1. //获取楼层数据
      2. async getFloorList(){
      3. const {data: res} = await uni.$http.get('/api/public/v1/home/floordata')
      4. if (res.meta.status !== 200) {
      5. return uni.$showMsg();
      6. }
      7. this.floorList = res.message;
      8. // console.log(this.floorList)
      9. }

    5.4.2. 渲染楼层标题

    1. 渲染出标题图片
      1. <!-- 楼层区 -->
      2. <!-- 楼层的容器 -->
      3. <view class="floor-list">
      4. <!-- 楼层的标题 -->
      5. <view class="florr" v-for="(item,i) in floorList" :key='i'>
      6. <image :src="item.floor_title.image_src" class="floor-title"></image>
      7. </view>
      8. </view>
    1. 样式
      1. .floor-title{
      2. height: 60rpx;
      3. width: 100%;
      4. }

    5.4.3. 渲染每个楼层中的图片

    1. 渲染出每个楼层中的图片
      1. <!-- 楼层的容器 -->
      2. <view class="floor-list">
      3. <!-- 楼层的标题 -->
      4. <view class="florr" v-for="(item, i) in floorList" :key="i">
      5. <image :src="item.floor_title.image_src" class="floor-title"></image>
      6. <!-- 楼层图片区域 -->
      7. <view class="floor-img-box">
      8. <!-- 左侧大图片的盒子 -->
      9. <view class="lefi-img-box">
      10. <image :src="item.product_list[0].image_src" :style="{ width: item.product_list[0].image_width + 'rpx' }" mode="widthFix"></image>
      11. </view>
      12. <!-- 右侧 4个小图片的盒子 -->
      13. <view class="right-img-box">
      14. <view class="right-img-item" v-for="(item, i2) in item.product_list" :key="i2" v-if="i2 != 0">
      15. <image :src="item.image_src" :style="{ width: item.image_width + 'rpx' }" mode="widthFix"></image>
      16. </view>
      17. </view>
      18. </view>
      19. </view>
      20. </view>
    1. 样式
      1. .right-img-box {
      2. display: flex;
      3. flex-wrap: wrap;
      4. justify-content: space-around;
      5. }
      6. .floor-img-box {
      7. display: flex;
      8. padding-left: 10rpx;
      9. }