4. 分类
4.1 实现分类页面基础结构
- 定义页面结构如下:
vue
<template>
<view>
<!-- 头部搜索框 -->
<view class="category-header van-hairline--bottom">
<navigator class="header-search" url="/subpkg/goods_list/goods_list">
<icon class="search-icon" type="search" size="13" color="#656771"></icon>
<text class="search-title">全场50元起步</text>
</navigator>
</view>
<!-- 分类内容 -->
<view class="search-wrap">
<!-- 左侧分类菜单 -->
<scroll-view class="nav-side-wrapper" scroll-y>
<view class="nav-side">
<view v-for="item in 10" :key="item">分类1</view>
</view>
</scroll-view>
<!-- 右侧分类内容 -->
<scroll-view class="search-content" scroll-y>
<view class="swiper-slide">
<view class="category-list" v-for="item in 3" :key="item">
<view class="category-title">标题1</view>
<view class="product-item" v-for="item in 10" :key="item">
<image src="//s.weituibao.com/1583591077131/%E5%88%86%E7%B1%BB.png" class="product-img"></image>
<view class="product-title">分类名</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</template>
- 美化页面结构
scss
// 搜索头部
.category-header {
background-color: #fff;
padding: 14rpx 30rpx;
color: #656771;
.header-search {
display: flex;
height: 46rpx;
padding: 10rpx 0;
background: #f7f7f7;
border-radius: 40rpx;
align-items: center;
justify-content: center;
font-size: 28rpx;
.search-icon {
margin-right: 10rpx;
color: #656771;
margin-top: 6rpx;
}
}
}
// 分类列表
.search-wrap {
display: flex;
justify-content: space-between;
background-color: #f8f8f8;
height: calc(100vh - 94rpx);
overflow: hidden;
.nav-side-wrapper {
width: 30%;
height: 100%;
.nav-side {
width: 100%;
box-sizing: border-box;
background-color: #f8f8f8;
.item {
width: 100%;
height: 112rpx;
text-align: center;
line-height: 112rpx;
font-size: 28rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
// 分类激活样式
&.active {
color: $uni-primary;
background-color: #fff;
}
}
}
}
.search-content {
width: 70%;
height: 100%;
padding: 0 20rpx;
background-color: #fff;
.swiper-slide {
width: 100%;
.category-list {
display: flex;
flex-wrap: wrap;
flex-shrink: 0;
width: 100%;
.category-title {
width: 100%;
font-size: 30rpx;
font-weight: 500;
padding: 40rpx 0;
}
.product-item {
width: 33.3333%;
margin-bottom: 20rpx;
text-align: center;
font-size: 30rpx;
.product-img {
width: 60rpx;
height: 60rpx;
}
}
}
}
}
}
4.2 获取分类数据
定义数据节点
jsconst state = reactive({ categoryData: [], currentIndex: 0 })
封装数据接口
jsimport http from '../index.js' // 获取分类数据 export function getCategory() { return http.get('/categories'); }
调用获取分类接口
jsonMounted(async () => { // 1. 显示加载 uni.showLoading({ title: '加载中...', mask: true }) // 2. 加载数据 const { data } = await getCategory() // 3. 设置数据 uni.hideLoading() state.categoryData = data state.currentIndex = data[0].categoryId })
4.3 动态渲染左侧的一级分类列表
循环渲染列表结构:
vue<!-- 左侧分类菜单 --> <scroll-view class="nav-side-wrapper" scroll-y> <view class="nav-side"> <view v-for="item in categoryData" :class="['item', { active: currentIndex === item.categoryId }]" :key="item.categoryId" > {{ item.categoryName }} </view> </view> </scroll-view>
在 data 中定义默认选中项的索引
jsconst state = reactive({ categoryData: [], currentIndex: 0 })
循环渲染结构时,为选中项动态添加
.active
类名:txt:class="['item', { active: currentIndex === item.categoryId }]"
为一级分类的 Item 项绑定点击事件处理函数
selectMenu
:txt@click="selectMenu(item.categoryId)"
定义
selectMenu
事件处理函数,动态修改选中项的索引:js// 选择分类 const selectMenu = index => { state.currentIndex = index }
4.4 动态渲染右侧的二级分类列表
循环渲染右侧二级分类列表的 UI 结构:
vue<!-- 右侧分类内容 --> <scroll-view class="search-content" scroll-y> <block v-for="(category, index) in categoryData" :key="category.categoryId"> <view class="swiper-slide" v-if="category.categoryId === currentIndex"> <view class="category-list" v-for="(products, index2) in category.secondLevelCategoryVOS" :key="products.categoryId"> <view class="category-title">{{ products.categoryName }}</view> ... </view> </view> </block> </scroll-view>
4.5 动态渲染右侧的三级分类列表
在二级分类的
<view>
组件中,循环渲染三级分类的列表结构:vue<view class="product-item" v-for="(product, index3) in products.thirdLevelCategoryVOS" :key="product.categoryId" @click="selectProduct(product)"> <image src="//s.weituibao.com/1583591077131/%E5%88%86%E7%B1%BB.png" class="product-img"></image> <view class="product-title">{{ product.categoryName }}</view> </view>
4.6 切换一级分类后重置滚动条的位置
4.7 点击三级分类跳转到商品列表页面
- 为三级分类的 Item 项绑定点击事件处理函数如下:
txt
<view class="product-item" v-for="(product, index3) in products.thirdLevelCategoryVOS" :key="product.categoryId" @click="selectProduct(product)">
- 定义事件处理函数如下:
js
// 根据分类选择商品
const selectProduct = item => {
console.log('item', item.categoryId)
uni.navigateTo({
url: `/subpkg/goods_list/goods_list?categoryId=${item.categoryId}`
})
}