分类
一级分类
一级分类设置
点击顶部导航栏跳转到对应的一级分类页面,按照如下步骤:
路由文件添加对应路由,这里采取把 id 添加到路由上,为必传项,因此需要
:
占位表示此数据为动态数据jsconst 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
属性定义要跳转的路径,改为对应 id 即可vue<RouterLink :to="`category/${item.id}`"> {{ item.name }} </RouterLink>
面包屑
面包屑导航主要步骤如下:
- 复制粘贴静态面包屑模板
- 封装接口函数
- 在面包屑
.vue
组件中引入接口函数,获取路由上的 id 作为参数传参 - 获取接口数据动态渲染
分类Banner
分类处轮播图主要步骤如下:
修改封装的轮播图接口,用于接收不同的参数(首页轮播图不用传,可使用默认值)
jsexport function getBannerAPI(params = {}) { const { distributionSite = '1' } = params return http({ url: '/home/banner', params: { distributionSite } }) }
封装轮播图组件以复用
vue<script setup> defineProps({ bannerList: { type: Array, required: true }, height: { type: [String, Number], default: 500 } }) /* * 点击轮播图 * e:当前被点击的轮播图的数据 */ function 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
模块负责自己的逻辑。返回需要的变量和方法后组件内部调用使用即可。
轮播图
jsimport { 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 } }
分类
jsimport { onMounted, ref } from 'vue' import { getTopCategoryAPI } from '@api/category' import { onBeforeRouteUpdate, useRoute } 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, } }
组件
vue<script setup> // 轮播图组件 import GoodsItem from '../Home/components/GoodsItem.vue' import { useBanner } from './composables/useBanner' import { useCategory } from './composables/useCategory' import BannerCarousel from '@/components/BannerCarousel.vue' const { bannerList } = useBanner() const { categoryData } = useCategory() </script>
这样后续无论是维护还是新增功能都很方便。
二级分类
创建
二级分类创建主要步骤如下:
设置静态模块
创建路由
js{ path: 'category/sub/:id', component: () => import('@/views/SubCategory/index.vue') },
在对应的
RouterLink
标签的to
属性中设置对应的跳转路径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
}
}
})