Vue 3 路由管理实战:从基础配置到性能优化
前言
在 Vue 3 项目中,路由管理是前端架构的重要组成部分。本文将结合一个电商项目实例,详细介绍 Vue Router 4 的配置、使用和性能优化策略。
一、路由基础配置
1.1 路由实例创建
javascript
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Layout from '@/views/Layout/index.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
component: Layout,
children: [
{
path: '',
component: () => import('@/views/Home/index.vue'),
},
{
path: '/category/:id',
component: () => import('@/views/Category/index.vue'),
},
{
path: '/category/sub/:id',
component: () => import('@/views/SubCategory/index.vue')
},
],
},
{
path: '/login',
component: () => import('@/views/Login/index.vue'),
},
],
scrollBehavior() {
return { top: 0 }
}
})
关键配置说明:
- createWebHistory(): 使用 HTML5 History API,支持更友好的 URL
- 路由懒加载: () => import() 实现代码分割
- scrollBehavior: 控制页面滚动行为
1.2 路由出口配置
html
<!-- src/App.vue -->
<template>
<RouterView />
</template>
<!-- src/views/Layout/index.vue -->
<template>
<LayoutNav />
<LayoutHeader />
<RouterView />
<LayoutFooter />
<LayoutFixed />
</template>
二、路由参数处理
2.1 动态路由参数
javascript
// 路由配置
{
path: '/category/:id',
component: () => import('@/views/Category/index.vue'),
// props: true // 将路由参数映射为 props
}
// 组件中使用
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const categoryId = route.params.id
</script>
2.2 路由参数监听
javascript
// src/views/Category/composables/useCategory.js
import { onBeforeRouteUpdate, useRoute } from 'vue-router'
const useCategory = () => {
const route = useRoute()
const categoryData = ref({})
const getCategoryData = (id = route.params.id) => {
if (!id) return
// 获取分类数据逻辑
}
// 路由参数变化时重新获取数据
onBeforeRouteUpdate((to) => {
getCategoryData(to.params.id)
})
onMounted(() => {
getCategoryData()
})
return { categoryData }
}
三、路由导航和状态管理
3.1 编程式导航
javascript
// 在组件中使用
import { useRouter } from 'vue-router'
const router = useRouter()
// 导航到指定路由
router.push('/category/1')
// 带参数的导航
router.push({
path: '/category/sub/2',
query: { sort: 'price' }
})
// 替换当前路由
router.replace('/login')
3.2 路由与状态管理结合
javascript
// src/stores/category.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useCategoryStore = defineStore('category', () => {
const urlList = ref([])
const getCategoryList = () => {
getLayoutData().then(res => {
if (res.code !== '1') {
console.error('获取分类数据失败', res)
return
}
urlList.value = res.result
})
}
return { urlList, getCategoryList }
})
// 在组件中使用
<script setup>
import { useCategoryStore } from '@/stores/category'
import { storeToRefs } from 'pinia'
const categoryStore = useCategoryStore()
const { urlList } = storeToRefs(categoryStore())
</script>
四、路由缓存优化
4.1 组件复用问题
在电商项目中,分类页面存在组件复用问题:
html
<template>
<LayoutNav />
<LayoutHeader />
<!-- 路由缓存问题:从 /category/1 到 /category/2 时,组件实例被复用 -->
<RouterView />
<LayoutFooter />
<LayoutFixed />
</template>
问题分析:
- 当路由参数变化时(如 /category/1 → /category/2),Vue Router 会复用组件实例
- 导致 onMounted 生命周期不会重新执行
- 数据不会自动更新
4.2 解决方案一:强制组件重建
vue
Apply to index.vue
优缺点:
- ✅ 简单直接,确保数据更新
- ❌ 性能浪费,每次都要重新创建组件
- ❌ 用户体验差,页面闪烁
4.3 解决方案二:路由守卫监听(推荐)
javascript
// src/views/Category/composables/useCategory.js
import { onBeforeRouteUpdate } from 'vue-router'
const useCategory = () => {
const categoryData = ref({})
const route = useRoute()
const getCategoryData = (id) => {
// 获取数据逻辑
}
// 关键:使用 onBeforeRouteUpdate 监听路由参数变化
onBeforeRouteUpdate((to) => {
getCategoryData(to.params.id)
})
onMounted(() => {
getCategoryData(route.params.id)
})
return { categoryData }
}
优势:
- ✅ 保持组件复用,性能更好
- ✅ 数据自动更新
- ✅ 用户体验流畅
4.4 解决方案三:使用 keep-alive 精确控制
html
<template>
<keep-alive :include="['Home', 'Category']">
<RouterView />
</keep-alive>
</template>
javascript
// 在组件中定义 name
<script>
export default {
name: 'Category'
}
</script>
五、路由性能优化
5.1 路由懒加载
js
// 基础懒加载
{
path: '/category/:id',
component: () => import('@/views/Category/index.vue')
}
// 预加载优化
{
path: '/category/:id',
component: () => import(/* webpackChunkName: "category" */ '@/views/Category/index.vue')
}
5.2 滚动行为优化
js
// 路由滚动行为定制,滚动条始终停留在顶部
// 参考:https://next.router.vuejs.org/zh/guide/advanced/scroll-behavior.html
scrollBehavior() {
return { top: 0 }
}
六、实际项目中的应用
6.1 面包屑导航
html
<template>
<el-breadcrumb separator=">">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item :to="`/category/${categoryData.parentId}`">
{{ categoryData.parentName }}
</el-breadcrumb-item>
<el-breadcrumb-item>{{ categoryData.name }}</el-breadcrumb-item>
</el-breadcrumb>
</template>
6.2 导航高亮
html
<template>
<ul class="header-nav">
<li>
<RouterLink to="/" :class="{ active: route.path === '/' }">
首页
</RouterLink>
</li>
<li v-for="item in urlList" :key="item.id">
<RouterLink
:to="`/category/${item.id}`"
active-class="active"
>
{{ item.name }}
</RouterLink>
</li>
</ul>
</template>
七、总结
通过本文的介绍,我们了解了 Vue Router 4 在 Vue 3 项目中的完整应用:
- 基础配置:路由实例创建、懒加载、滚动行为
- 参数处理:动态路由、参数监听、编程式导航
- 状态管理:与 Pinia 结合使用
- 缓存优化:解决组件复用问题的最佳实践
- 性能优化:懒加载、预加载、keep-alive
在实际项目中,合理使用这些技术可以构建出高性能、易维护的路由系统,提升用户体验和开发效率。