商品分类-效果图
分类-静态结构
src/pages/category/index.vue
vue
<template>
<view class="viewport">
<!-- 搜索框 -->
<view class="search">
<view class="input">
<text class="icon-search">女靴</text>
</view>
</view>
<!-- 分类 -->
<view class="categories">
<!-- 分类左侧 -->
<scroll-view class="primary" scroll-y>
<view class="item active">居家</view>
<view class="item">美食</view>
<view class="item">服饰</view>
<view class="item">母婴</view>
<view class="item">个护</view>
</scroll-view>
<!-- 分类右侧 -->
<scroll-view class="secondary" scroll-y>
<!-- 轮播图 -->
<Carousel class="banner" height="200rpx" />
<view class="panel">
<view class="title">
居家生活用品
<navigator
class="more"
hover-class="none"
url="/pages/goods/list/index"
>全部</navigator
>
</view>
<view class="section">
<navigator
hover-class="none"
url="`/pages/goods/index?id=${goods.id}`"
>
<image
src="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-05/7f483771-6831-4a7a-abdb-2625acb755f3.png"
/>
<view class="name ellipsis">极光限定 珠光蓝珐琅锅</view>
<view class="price">
<text class="symbol">¥</text>
<text class="number">xxx.00</text>
</view>
</navigator>
<navigator
hover-class="none"
url="`/pages/goods/index?id=${goods.id}`"
>
<image
src="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-05/6fdcac19-dd44-442c-9212-f7ec3cf3ed18.jpg"
/>
<view class="name ellipsis">钻石陶瓷涂层多用锅18cm 小奶锅</view>
<view class="price">
<text class="symbol">¥</text>
<text class="number">xxx.00</text>
</view>
</navigator>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {};
</script>
<style lang="scss">
page {
height: 100%;
overflow: hidden;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
}
.search {
padding: 0 30rpx 20rpx;
background-color: #fff;
.input {
display: flex;
align-items: center;
justify-content: space-between;
height: 64rpx;
padding-left: 26rpx;
color: #8b8b8b;
font-size: 28rpx;
border-radius: 32rpx;
background-color: #f3f4f4;
}
}
.icon-search {
&::before {
margin-right: 10rpx;
}
}
/* 分类 */
.categories {
flex: 1;
min-height: 400rpx;
display: flex;
}
/* 主分类 */
.primary {
overflow: hidden;
width: 180rpx;
flex: none;
background-color: #f6f6f6;
.item {
height: 96rpx;
text-align: center;
line-height: 96rpx;
font-size: 26rpx;
color: #595c63;
position: relative;
&::after {
position: absolute;
left: 42rpx;
bottom: 0;
content: "";
width: 96rpx;
border-top: 1rpx solid #e3e4e7;
}
}
.active {
background-color: #fff;
&::before {
position: absolute;
left: 0;
top: 0;
content: "";
width: 8rpx;
height: 100%;
background-color: #27ba9b;
}
}
}
.primary .item:last-child::after,
.primary .active::after {
display: none;
}
/* 次分类 */
.secondary {
background-color: #fff;
.banner {
height: 200rpx;
margin: 30rpx;
border-radius: 4rpx;
overflow: hidden;
}
.panel {
margin: 0 30rpx 0rpx;
}
.title {
height: 60rpx;
line-height: 60rpx;
color: #333;
font-size: 28rpx;
border-bottom: 1rpx solid #f7f7f8;
.more {
float: right;
padding-left: 20rpx;
font-size: 24rpx;
color: #999;
}
}
.more {
&::after {
font-family: "erabbit" !important;
content: "\e6c2";
}
}
.section {
width: 100%;
display: flex;
flex-wrap: wrap;
padding: 20rpx 0;
navigator {
width: 150rpx;
margin: 0rpx 30rpx 20rpx 0;
&:nth-child(3n) {
margin-right: 0;
}
}
}
navigator {
image {
width: 126rpx;
height: 126rpx;
}
.name {
font-size: 26rpx;
color: #333;
}
.price {
font-size: 18rpx;
color: #cf4444;
}
.number {
font-size: 24rpx;
margin-left: 2rpx;
}
}
}
</style>
一级分类-效果图
一级分类-请求数据、渲染界面
步骤:
1、封装API
src\api\category.js
js
/** 请求分类数据 */
export const getCategoriesAPI = () => {
return request({ url: "/category/top" });
};
2、封装请求函数,调用API
3、加载后,触发请求函数
4、声明变量,保存数据
vue
<script>
import { getCategoriesAPI } from "@/api/category";
export default {
// 4. 声明变量,保存数据
data() {
return {
topList: [],
};
},
methods: {
// 2. 封装请求函数
async loadData() {
const { result } = await getCategoriesAPI();
this.topList = result;
},
},
// 3. 创建后发请求
onLoad() {
this.loadData();
},
};
</script>
5、列表渲染插值显示
vue
<scroll-view class="primary" scroll-y>
<view
v-for="(item, index) in topList"
:key="item.id"
class="item"
:class="{ active: true }"
>
{{ item.name }}
</view>
</scroll-view>
一级分类-点谁谁高亮
目标:实现一级分类,点谁谁高亮
核心:排它判断+数据驱动视图
步骤:
- 声明变量
activeIndex:0
- 动态class, 根据
activeIndex
,添加类名active
- 点击事件,修改
activeIndex
代码省略...
二级分类-效果图
二级分类-静态结构
vue
<scroll-view class="secondary" scroll-y >
<!-- 复用轮播图组件 -->
<Carousel class="banner" height="200rpx" />
</scroll-view>
二级分类-请求数据、渲染轮播图
目标:实现渲染轮播图
步骤:
- 复用接口请求数据
- 调用请求方法
- 声明变量,保存数据
- 复用轮播图组件,渲染界面
代码:
- 复用接口请求数据
- 调用请求方法
diff
methods: {
async loadBanners() {
// 1. 复用接口请求数据
+ const { result } = await getBannersAPI(2);
+ this.banners = result;
},
},
created() {
// 2. 调用请求方法
+ this.loadBanners();
},
- 复用轮播图组件,渲染界面
html
<Carousel class="banner" height="200rpx" :banners="banners" />
二级分类-渲染内容列表
目标:实现渲染内容列表
思路:根据选中的activeIndex
, 一级分类列表,计算得出二级列表的数据,渲染界面。
步骤:
- 定义计算属性
subList
,根据activeIndex
和topList
,计算二级列表数据 - 列表渲染
代码:
js
computed: {
// 1. 定义计算属性subList
subList() {
if (!this.topList.length) return [];
return this.topList[this.activeIndex].children;
},
},
vue
<!-- 2. 列表渲染 -->
<view class="panel" v-for="item in subList" :key="item.id">
<view class="title">
{{ item.name }}
<navigator
class="more"
hover-class="none"
url="/pages/goods/list/index"
>全部</navigator
>
</view>
<view class="section">
<navigator
v-for="goods in item.goods"
:key="goods.id"
hover-class="none"
:url="`/pages/goods/index?id=${goods.id}`"
>
<image :src="goods.picture"></image>
<view class="name ellipsis">{{ goods.name }}</view>
<view class="price">
<text class="symbol">¥</text>
<text class="number">{{ goods.price }}</text>
</view>
</navigator>
</view>
</view>