一级分类 - banner轮播图实现
分类轮播图实现
分类轮播图和首页轮播图的区别只有一个,接口参数不同,其余逻辑完成一致
- 适配接口
export function getBannerAPI (params = {}) {
// 默认为1 商品为2
const { distributionSite = '1' } = params
return httpInstance({
url: '/home/banner',
params: {
distributionSite
}
})
}
- 迁移首页Banner逻辑
<script setup>
// 部分代码省略
import { getBannerAPI } from '@/apis/home'
// 获取banner
const bannerList = ref([])
const getBanner = async () => {
const res = await getBannerAPI({
distributionSite: '2'
})
console.log(res)
bannerList.value = res.result
}
onMounted(() => getBanner())
</script>
<template>
<div class="top-category">
<div class="container m-top-20">
<!-- 面包屑 -->
<div class="bread-container">
<el-breadcrumb separator=">">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>{{ categoryData.name }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- 轮播图 -->
<div class="home-banner">
<el-carousel height="500px">
<el-carousel-item v-for="item in bannerList" :key="item.id">
<img :src="item.imgUrl" alt="">
</el-carousel-item>
</el-carousel>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
// 部分代码省略
.home-banner {
width: 1240px;
height: 500px;
margin: 0 auto;
img {
width: 100%;
height: 500px;
}
}
</style>
一级分类 - 激活状态显示和分类列表渲染
激活状态显示
RouterLink组件默认支持激活样式显示的类名,只需要给active-class属性设置对应的类名
即可
<RouterLink active-class="active" :to="`/category/${item.id}`">{{item.name}}</RouterLink>
.active {
color: $xtxColor;
border-bottom: 1px solid $xtxColor;
}
分类列表渲染
分类的数据已经在面包屑导航实现的时候获取到了,只需要通过v-for遍历出来即可
<div class="sub-list">
<h3>全部分类</h3>
<ul>
<li v-for="i in categoryData.children" :key="i.id">
<RouterLink to="/">
<img :src="i.picture" />
<p>{{ i.name }}</p>
</RouterLink>
</li>
</ul>
</div>
<div class="ref-goods" v-for="item in categoryData.children" :key="item.id">
<div class="head">
<h3>- {{ item.name }}-</h3>
</div>
<div class="body">
<GoodsItem v-for="good in item.goods" :goods="good" :key="good.id" />
</div>
</div>
一级分类 - 解决路由缓存问题
什么是路由缓存问题?
问题:一级分类的切换正好满足上面的条件,组件实例复用,导致分类数据无法更新
解决问题的思路:1. 让组件实例不复用,强制销毁重建 2. 监听路由变化,变化之后执行数据更新操作
方案一:给router-view添加key
以当前路由完整路径为key的值,给router-view组件绑定
<RouterView :key="$route.fullPath"/>
方案二:使用beforeRouteUpdate导航钩子
beforeRouteUpdate钩子函数可以在每次路由更新之前执行,在回调中执行需要数据更新的业务逻辑
即可
- 路由缓存问题产生的原因是什么?
路由只有参数变化时,会复用组件实例 - 俩种方案都可以解决路由缓存问题,如何选择呢?
在意性能问题,选择onBeforeUpdate, 精细化控制
不在意性能问题,选择key,简单粗暴
一级分类 - 使用逻辑函数拆分业务
概念理解
基于逻辑函数拆分业务是指把同一个组件中独立的业务代码通过函数做封装处理
,提升代码的可维护性
。
具体怎么做
实现步骤:
- 按照业务声明以
use
打头的逻辑函数 - 把
独立的业务逻辑
封装到各个函数内部 - 函数内部把组件中需要用到的数据或者方法
return出去
- 在
组件中调用函数
把数据或者方法组合回来使用
useBanner.js
// 封装banner轮播图相关的业务代码
import { ref,onMounted } from 'vue'
import { getBannerAPI } from "@/apis/home";
export function useBanner() {
const bannerList = ref([]);
const getBanner = async () => {
const res = await getBannerAPI({ distributionSite: "2" });
console.log(res);
bannerList.value = res.result;
};
onMounted(() => getBanner());
return {
bannerList
}
}
useCategory.js
// 封装分类数据业务相关代码
import { getCategoryAPI } from "@/apis/category";
import { useRoute } from "vue-router";
import { onBeforeRouteUpdate } from 'vue-router'
import { onMounted, ref } from "vue";
export function useCategory() {
const categoryData = ref({});
const route = useRoute();
const getCategory = async (id = route.params.id) => {
const res = await getCategoryAPI(id);
categoryData.value = res.result;
};
onMounted(() => getCategory());
// 目标:路由参数变化的时候 可以把分类数据接口重新发送
onBeforeRouteUpdate((to) => {
console.log('路由变化了');
getCategory(to.params.id)
})
return {
categoryData
}
}
核心思想总结
-
逻辑拆分的过程是一个拆分再组合的过程
-
函数use打头,内部封装逻辑,return组件需要用到的数据和方法给组件消费