1. 一级分类-整体认识和路由配置
1)当点击一级分类的时候,会路由跳转到Category组件,并传递参数过去。
所以需要在Category组件进行路由配置,进行参数的占位。
2)配置导航区域链接
因为点击LayoutHeader,LayoutFixed组件都会进行路由跳转。所以都需要配置链接,传递参数。
2. 一级分类-面包屑导航渲染
步骤:
1)准备静态组件
2)封装接口
//src/apis/category.js
import request from "@/utils/http";
// 获取分类数据
export function getCategoryAPI(id){
return request({url:'/category',params:{id}})
}
3)获取数据
注意这里有参数传过来,所以需要使用useRoute来获取参数
//src/views/Category/index.vue
<script setup>
import { getCategoryAPI } from "@/apis/category";
import { onMounted, ref } from "vue";
import { useRoute } from "vue-router";
// 获取数据
const categoryData = ref({});
// 使用useRoute获取传过来的参数
const route = useRoute();
const getCategory = async () => {
const res = await getCategoryAPI(route.params.id);
categoryData.value = res.result;
};
onMounted(() => {
getCategory();
});
渲染页面
3. 一级分类-banner轮播图实现
由于分类的轮播图和首页的轮播图是一样的,只是接口的参数不同,所以其他步骤一样。
步骤:
1)适配接口参数
//src/apis/home.js
// 获取banner
export function getBannerAPI(params={}){
// 默认为1 商品为2
const {distributionSite='1'}=params
return httpInstance({
url:'/home/banner',
params:{
distributionSite
}
})
}
2)迁移首页Banner逻辑,获取数据,渲染数据
//src/views/Category/index.vue
<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>
4. 一级分类-激活状态显示和分类列表渲染
激活状态显示
RouterLink组件默认支持激活样式显示的类名,只需要给 active-class属性设置对应的类名 即可
分类列表渲染
//src/views/Category/index.vue
<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>
注意:这里引用了GoodsItem组件,所以记得引入进去。
5. 一级分类-解决路由缓存问题
当组件实例复用了,生命周期钩子函数就不会调用,就不会执行里面的函数,所以就得不到数据。一级分类就是如此,当我们点击时,只是参数的变化,所以我们需要解决路由缓存。
解决方法:
方法一:让组件实例不复用,强制销毁重建。
方法一存在的问题:因为 轮播图是一样的,所以不需要每一次都重新获取一次,消耗性能。
方法二:监听路由变化,变化之后执行数据更新操作
在src/views/Category/index.vue中
6.一级分类-使用逻辑函数拆分业务
需求:把同一个组件中的独立的代码通过函数封装起来,方便以后维护。
在category分类页面,就是获取分类的代码和获取轮播图的代码。
把这两个逻辑代码封装。
步骤:
1)在Category中创建composables文件夹,存储这两段代码。
2)把独立的逻辑代码封装到函数中
//src/views/Category/composables/userBanner.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();
});
// 此时的bannerList在另一个文件里面需要使用,使用要return出去
return {
bannerList
}
}
//src/views/Category/composables/userCategory.js
// 封装分类数据业务相关的代码
import {ref,onMounted} from 'vue'
import {onBeforeRouteUpdate, useRoute } from "vue-router";
import { getCategoryAPI } from "@/apis/category";
export function useCategory() {
// 获取分类数据
const categoryData = ref({});
// 使用useRoute获取传过来的参数
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('路由变化了');
// 存在的问题:使用最新的路由参数请求最新的分类数据
console.log(to);
getCategory(to.params.id)
})
return {categoryData}
}
3)在组件中调用函数
核心思想:
总结:
1.在vue3中,路由传参记得使用useRoute来传递参数。
2.在轮播图实现中,由于只是和首页轮播图的接口参数不同,所以可以通过适配接口来使用同样的函数。
3.在使用带参数的路由时,相同的组件实例会被重复使用,生命周期钩子函数也不会被调用,所以需要解决路由缓存问题。
4.在同一个组件中,如果有多个独立的代码,可以通过以'use'开头的函数封装起来,后期通过调用函数来实现,也有利于后期的维护。(记得return 出去)