分类
刀刀
1/2/2025
0 字
0 分钟
一级分类
一级分类设置
点击顶部导航栏跳转到对应的一级分类页面,按照如下步骤:
路由文件添加对应路由,这里采取把 id 添加到路由上,为必传项,因此需要
:
占位表示此数据为动态数据页面中通过
RouterLink
组件的to
属性定义要跳转的路径,改为对应 id 即可
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
// path和component对应关系的位置
routes: [
{
path: '/',
component: Layout,
children: [
// ...
{
path: 'category/:id',
component: () => import('@/views/Category/index.vue')
},
]
},
],
})
<RouterLink :to="`category/${item.id}`">{{ item.name }}</RouterLink>
面包屑
面包屑导航主要步骤如下:
- 复制粘贴静态面包屑模板
- 封装接口函数
- 在面包屑
.vue
组件中引入接口函数,获取路由上的 id 作为参数传参 - 获取接口数据动态渲染
分类Banner
分类处轮播图主要步骤如下:
修改封装的轮播图接口,用于接收不同的参数(首页轮播图不用传,可使用默认值)
封装轮播图组件以复用
分类组件中引入使用(首页轮播图也可使用复用的组件),然后单独对应参数获取对应数据即可
export const getBannerAPI = (params = {}) => {
const { distributionSite = '1' } = params
return http({
url: '/home/banner',
params: {
distributionSite
}
})
}
<script setup>
defineProps({
bannerList: {
type: Array,
required: true
},
height: {
type: [String, Number],
default: 500
}
})
/*
* 点击轮播图
* e:当前被点击的轮播图的数据
*/
const handleCarouselFn = e => {
// this.$router.push(e.hrefUrl)
}
</script>
<template>
<el-carousel :height="height + 'px'">
<el-carousel-item v-for="item in bannerList" :key="item.id" @click="handleCarouselFn(item)">
<img :src="item.imgUrl" alt="">
</el-carousel-item>
</el-carousel>
</template>
<style scoped>
</style>
导航激活设置分类列表渲染
导航激活
点击对应导航却没有相应的激活样式,不利于用户体验。而组件
RouterLink
有一个属性active-class
,当其to
属性的值与路由的值匹配,则会处于激活状态,获取等号后的激活样式。vue<RouterLink active-class="active" :to="`/category/${item.id}`">{{ item.name }}</RouterLink>
现在为
active
做对应的样式设置即可。分类渲染
渲染对应内容即可。
路由缓存
Vue
官方文档有一段说明:使用带参数的路由时,当用户从 /category/01
跳转到 /category/02
时,相同的组件实例将会被重复使用,减少性能消耗。但是这也意味着生命周期钩子不会被调用。
解决思路:
- 让组件实例不再复用,强制销毁重建
- 监听路由变化,变化后执行数据更新操作
方案一
在 Vue
中,:key
不仅可以用来配合 v-for
使用,同时也能作用于强制替换一个元素、组件而不是复用它。
在二级路由处添加 :key
属性,值为当前完整路由,代码如下:
<router-view :key="$route.fullPath"></router-view>
刷新后查看页面,发现效果实现了,但是有一个问题,我们只需要内容区域接口重新获取,而它把不需要重新调用的轮播图接口也重复请求。如果接口多的话,这样很影响性能。
方案二
Vue
路由提供了一个方法 onBeforeRouteUpdate
,在路由参数发生变化时触发。其中有一个 to
参数,接收最新的路由参数。因此获取最新的路由参数的 id
,单纯调用分类接口,这样不至于消耗太大的性能。
import { onBeforeRouteUpdate } from "vue-router";
/**
* 侦听路由变化,重新调用接口
* to:当前最新路由参数
* */
onBeforeRouteUpdate((to) => {
// 存在问题:使用最新的路由参数请求最新的分类数据
getTopCategoryFn(to.params.id);
})
逻辑函数拆分业务
分类模块根据业务逻辑拆分,每个 js
模块负责自己的逻辑。返回需要的变量和方法后组件内部调用使用即可。
轮播图
分类
组件
import { onMounted, ref } from "vue";
import { getBannerAPI } from "@api/layout";
export function useBanner() {
const bannerList = ref([]); // 轮播图数组
const getBannerFn = async () => {
const res = await getBannerAPI({
distributionSite: "2",
});
bannerList.value = res.result;
};
onMounted(() => {
getBannerFn();
});
return {
bannerList
}
}
import { onMounted, ref } from "vue";
import { getTopCategoryAPI } from "@api/category";
import { useRoute, onBeforeRouteUpdate } from "vue-router";
export function useCategory() {
const categoryData = ref({}); // 分类数据
const route = useRoute(); // 路由对象
const getTopCategoryFn = async (id) => {
const res = await getTopCategoryAPI(id);
categoryData.value = res.result;
};
onMounted(() => getTopCategoryFn(route.params.id));
/**
* 侦听路由变化,重新调用接口
* to:当前最新路由参数
* */
onBeforeRouteUpdate((to) => {
// 存在问题:使用最新的路由参数请求最新的分类数据
getTopCategoryFn(to.params.id);
})
return {
categoryData,
}
}
<script setup>
// 轮播图组件
import BannerCarousel from "@/components/BannerCarousel.vue";
import GoodsItem from "../Home/components/GoodsItem.vue";
import { useBanner } from './composables/useBanner'
import { useCategory } from './composables/useCategory'
const { bannerList } = useBanner()
const { categoryData } = useCategory()
</script>
这样后续无论是维护还是新增功能都很方便。
二级分类
创建
二级分类创建主要步骤如下:
设置静态模块
创建路由
在对应的
RouterLink
标签的to
属性中设置对应的跳转路径
{
path: 'category/sub/:id',
component: () => import('@/views/SubCategory/index.vue')
}
<RouterLink :to="`/category/sub/${i.id}`">
面包屑
封装接口获取面包屑数据
动态设置面包屑名称,通过返回的面包屑的父亲
id
拼接的方式设置跳转路径vue<el-breadcrumb separator=">"> <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item> <el-breadcrumb-item :to="{ path: `/category/${subCategoryData.parentId}` }" >{{ subCategoryData.parentName }} </el-breadcrumb-item> <el-breadcrumb-item>{{ subCategoryData.name }}</el-breadcrumb-item> </el-breadcrumb>
分类模块
首先封装接口函数,调用接口获取数据,引入之前封装好的商品模块组件即可
列表筛选模块主要是根据传参的不同实现
列表无限滚动则是根据
elementPlus
提供的v-infinite-scroll
指令判断触底,满足条件后页码自增1,获取新数据后做新老数据拼接渲染基础用法
在要实现滚动加载的列表上上添加
v-infinite-scroll
,并赋值相应的加载方法,可实现滚动到底部时自动执行加载方法。禁用只需添加
:infinite-scroll-disabled="disabled"
,disabled
为真即可。
路由滚动行为设置
切换二级分类后想要页码返回顶部,可以使用 vue-router
提供的 scrollBehavior
方法,方法使用如下:
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
// path和component对应关系的位置
routes: [
// ...
],
// 路由滚动行为定制
scrollBehavior (to, from, savedPosition) {
return {
top: 0
}
}
})