黑马优购小程序之分类模块

1.1 目标效果图

首先,看下本节要实现的效果图:
在这里插入图片描述
由图分析:

  • 上方是一个搜索
  • 左侧是分类滑动scroll-view
  • 右侧是类别详情内容,也是一个scroll-view

1.2 网络请求和数据解析

1.2.1 数据解析

该接口数据返回格式为:

{
    "message":[
        {
            "cat_id":1,
            "cat_name":"大家电",
            "cat_pid":0,
            "cat_level":0,
            "cat_deleted":false,
            "cat_icon":"/full/none.jpg",
            "children":[
                {
                    "cat_id":3,
                    "cat_name":"电视",
                    "cat_pid":1,
                    "cat_level":1,
                    "cat_deleted":false,
                    "cat_icon":"/full/none.jpg",
                    "children":[
                        {
                            "cat_id":5,
                            "cat_name":"曲面电视",
                            "cat_pid":3,
                            "cat_level":2,
                            "cat_deleted":false,
                            "cat_icon":"https://api-hmugo-web.itheima.net/full/2fb113b32f7a2b161f5ee4096c319afedc3fd5a1.jpg"
                        },
                        {
                            "cat_id":6,
                            "cat_name":"海信",
                            "cat_pid":3,
                            "cat_level":2,
                            "cat_deleted":false,
                            "cat_icon":"https://api-hmugo-web.itheima.net/full/5e38cf9e6e7c46a17fe1c597a883ae627977b296.jpg"
                        }
                    ]
                }
            ]
        }
    ]
}

此处message中为三套循环,第一层为左侧分类列表,第二层为分类中小类,第三层为详细产品。

1.2.2 构建网络请求,处理数据

category/index.js中,声明所需数据:

  /**
   * 页面的初始数据
   */
  data: {

    // 左侧菜单数组
    leftMenuList: [],
    // 右侧商品数组
    rightContent: []
  },
  // 定义变量接受server返回整体数据
  Cates: [],

引入之前设计的request

import { request } from "../../request/index.js"

发送网络请求并处理数据:

/**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.getCates();
  },

  /* 
    加载分类数据
  */
  getCates() {
    request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/categories"
    }).then(result => {
      console.log(result)
      this.Cates = result.data.message;
      // 构造左侧大菜单数据
      let leftMenuList = this.Cates.map(v => v.cat_name);
      // 构造右侧商品数据
      let rightContent = this.Cates[0].children;
      this.setData({
        leftMenuList,
        rightContent
      })
    })
  },

1.3 绘制UI

1.3.1 引入自定义组件

分类页面头部是一个搜索框,这个组件在上一节中已经做了处理,那在这里直接引用即可。

category/index.json中,引入组件:

{
  "usingComponents": {
    "SearchInput":"../../components/SearchInput/SearchInput"
  },
  "navigationBarTitleText": "商品分类"
}

category/index.wxml中,使用组件:

<view class="cates">
    <SearchInput></SearchInput>
</view>

效果如下:
在这里插入图片描述

1.3.2 页面左右分割

首先,将页面左右分开布局,
category/index.wxml中,编写布局

    <view class="cates_container">
        <!-- 左侧菜单 -->
        <scroll-view class="left_menu" scroll-y>
        </scroll-view>
        <!-- 右侧商品内容 -->
        <scroll-view class="right_content" scroll-y>
            
        </scroll-view>
    </view>

category/index.less文件中,编写样式文件:

page {
    height: 100%;
}

.cates {
    height: 100%;

    .cates_container {
        /* 在less中使用calc时要注意 */
        height : ~'calc(100vh - 90rpx)';
        display: flex;

        .left_menu {
            flex: 2;
            background-color: hotpink;
        }

        .right_content {
            flex: 5;
            background-color: gold;
            
        }
    }
}

效果如下:
在这里插入图片描述

1.3.3 左侧菜单列表

左侧菜单,需要对leftMenuList进行循环,并先完成简单样式。
category/index.wxml中,编写菜单遍历代码:

<!-- 左侧菜单 -->
<scroll-view class="left_menu" scroll-y>
    <view class="menu_item" wx:for="{{leftMenuList}}" wx:key="*this">{{item}}</view>
</scroll-view>

category/index.less文件中,编写样式代码:

.cates {
    height: 100%;

    .cates_container {
        /* 在less中使用calc时要注意 */
        height : ~'calc(100vh - 90rpx)';
        display: flex;

        .left_menu {
            flex: 2;

            .menu_item {
                height         : 80rpx;
                justify-content: center;
                align-items    : center;
                font-size      : 30rpx;
                display        : flex;
            }
        }
    }

}

效果如下:
在这里插入图片描述

1.3.4 右侧商品子类别

这里,主要两个循环,第一层为子分类标题,第二层为子分类列表内容。

category/index.wxml中,编写UI,代码如下:

<!-- 右侧商品内容 -->
<scroll-view class="right_content" scroll-y>
    <view class="goods_group" wx:for="{{rightContent}}" wx:for-index="cate_index" wx:key="cat_id" wx:for-item="cate_item">
        <!-- 商品标题 -->
        <view class="goods_title">
            <text class="delimiter">/</text>
            <text class="title">{{cate_item.cat_name}}</text>
            <text class="delimiter">/</text>
        </view>
        <!-- 商品分类 -->
        <view class="goods_list">
            <navigator wx:for="{{cate_item.children}}" wx:for-item="good_item" wx:for-index="good_index" wx:key="cat_id">
                <image mode="widthFix" src="{{good_item.cat_icon}}" />
                <view class="goods_name">{{good_item.cat_name}}</view>
            </navigator>
        </view>
    </view>
</scroll-view>

catrgory/index.less中编写样式,如下:

.right_content {
     flex: 5;
     .goods_group {
         .goods_title {
             height         : 80rpx;
             display        : flex;
             justify-content: center;
             align-items    : center;

             .delimiter {
                 color  : #ccc;
                 padding: 0 10rpx;
             }

             .title {}
         }
     }

     .goods_list {
         display  : flex;
         flex-wrap: wrap;

         navigator {
             width     : 33.33%;
             text-align: center;

             image {
                 width: 50%;
             }

             .goods_name {
                 padding-bottom: 8rpx;
             }
         }
     }
 }

实现效果如下:
在这里插入图片描述

1.3 点击菜单切换商品内容

接下来,需要实现,点击左侧菜单,出现选中样式,并且,右侧商品内容同步更新。

1.3.1 选中菜单添加active样式

首先需要在点击左侧菜单时,样式更新。

categry/index.less中,编写选中样式文件:

.left_menu {
    flex: 2;

    .menu_item {
        height         : 80rpx;
        justify-content: center;
        align-items    : center;
        font-size      : 30rpx;
        display        : flex;
    }

    .active{
        color: var(--themeColor);
        border-left: 5rpx solid currentColor;
    }
}

category/index.js中,记录当前索引值:

  data: {

    // 左侧菜单数组
    leftMenuList: [],
    // 右侧商品数组
    rightContent: [],
    // 选择菜单索引
    currentIndex: 0
  },

category/index.wxml中,判断索引,添加样式:

<!-- 左侧菜单 -->
 <scroll-view class="left_menu" scroll-y>
     <view class="menu_item {{currentIndex===index?'active':''}}" wx:for="{{leftMenuList}}" wx:key="*this">{{item}}</view>
 </scroll-view>

此时,仅有第一个是选中样式,当点击菜单是没有效果的,因为还没设置点击事件,接下来添加一下吧。

category/index.wxml中,给左侧菜单添加点击事件,并把当前索引传入。

<!-- 左侧菜单 -->
<scroll-view class="left_menu" scroll-y>
    <view class="menu_item {{currentIndex===index?'active':''}}" wx:for="{{leftMenuList}}" wx:key="*this" bind:tap="handItemTab" data-index="{{index}}">{{item}}</view>
</scroll-view>

category/index.js中,添加处理函数,并更新currentIndex

// 菜单点击事件
handItemTab(e){
    console.log(e);
    // 获取索引
    const {index} = e.currentTarget.dataset;
    this.setData({
      currentIndex: index
    })
},

这样,即完成菜单点击效果的切换。

1.3.2 动态切换右侧商品内容

根据点击菜单,更新右侧商品内容,只需要通过index获取商品数据即可

// 菜单点击事件
handItemTab(e){
   console.log(e);
   // 获取索引
   const {index} = e.currentTarget.dataset;
   // 更新右侧商品数据
   let rightContent = this.Cates[index].children;
   this.setData({
     currentIndex: index,
     rightContent
   })
},

如上,就完成了右侧内容的动态切换。

1.4 缓存

以商品分类接口为例,其返回数据较多,在网络不好的情况较慢,无论是在用户体验还是技术角度都是不好的,实际项目中,需要对这种变化频率不高、数据量较大的接口增加缓存。

实现方案如下:

  • 检查本地有无缓存,如果没有,网络请求数据,并缓存到本地
  • 如果有,检查是否过期。如过期,网络请求,并缓存到本地
  • 如果未过期,直接使用数据即可
1.4.1 更新UI代码抽取

将更新UI代码操作,抽取独立方法,如下:

/* 更新UI */
updateUI() {
  // 构造左侧大菜单数据
  let leftMenuList = this.Cates.map(v => v.cat_name);
  // 构造右侧商品数据
  let rightContent = this.Cates[0].children;
  this.setData({
    leftMenuList,
    rightContent
  })
},
1.4.2 本地存储数据

在网络请求后,调用小程序API存储数据:

/* 
    加载分类数据
  */
getCates(){
  request({
    url: "https://api-hmugo-web.itheima.net/api/public/v1/categories"
  }).then(result => {
    console.log(result)
    this.Cates = result.data.message;
    // 本地存储数据
    wx.setStorageSync("cates", { time: Date.now(), data: this.Cates });
    this.updateUI();
  })
},
1.4.2 缓存设计实现

在页面onLoad方法中,根据思路,假如本地缓存判断相关代码,详细如下:

/**
 * 生命周期函数--监听页面加载
 */
onLoad: function (options) {
  // 获取本地存储数据
  const localCates = wx.getStorageSync("cates");
  if (!localCates) {
    // 本地没有,网络请求
    this.getCates();
  } else {
    // 本地有数据,判断是否过期 此处为60秒
    if (Date.now() - localCates.time > 1000 * 10 * 6) {
      // 数据过期
      this.getCates();
    } else {
      // 本地数据有效
      this.Cates = localCates.data;
      this.updateUI();
    }
  }
},

如上,完成后可自行测试,绝对生效了~

1.5 切换菜单,右侧列表回顶部

现在分类页面还存在一个问题,当选中一个菜单,右边内容向下滚动后,再次点菜单按钮,右侧内容显示没有回顶部,效果如下:
在这里插入图片描述
接下来,修复一下这个问题,其实也很简单,scroll-view提供了一个属性scrollTop,在切换左侧菜单的时候,将其属性设置为0即可。

1.5.1 声明scrollToTop属性

category/index.js中的Page data中,声明属性,如下:

// 右侧内容的滚动条
scrollToTop: 0
1.5.2 处理菜单点击事件

在点击事件中,对当前点击菜单进行判断:

 // 菜单点击事件
 handItemTab(e) {
   console.log(e);
   // 获取索引
   const { index } = e.currentTarget.dataset;
   // 如果重复点击标签,不做操作
   if(index==this.data.currentIndex){
     return;
   }
   // 更新右侧商品数据
   let rightContent = this.Cates[index].children;
   this.setData({
     currentIndex: index,
     rightContent,
     scrollToTop: 0
   })
 },
1.5.3 添加scrollTop属性

category/index.wxml中给scroll-view添加属性

<!-- 右侧商品内容 -->
<scroll-view class="right_content" scroll-y scroll-top="{{scrollToTop}}">
....
</scroll-view>

1.6 小结

本节初步完成了分类页面的展示,关键点如下:

  • 左菜单右内容UI布局
  • scroll-view使用及注意事项
  • 缓存处理
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值