Vue 3 路由管理实战:从基础配置到性能优化

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 项目中的完整应用:

  1. 基础配置:路由实例创建、懒加载、滚动行为
  1. 参数处理:动态路由、参数监听、编程式导航
  1. 状态管理:与 Pinia 结合使用
  1. 缓存优化:解决组件复用问题的最佳实践
  1. 性能优化:懒加载、预加载、keep-alive

在实际项目中,合理使用这些技术可以构建出高性能、易维护的路由系统,提升用户体验和开发效率。

相关推荐
码哥DFS8 分钟前
Flex布局原理
前端·css·css3
小样还想跑24 分钟前
axios无感刷新token
前端·javascript·vue.js
Java水解34 分钟前
一文了解Blob文件格式,前端必备技能之一
前端
用户3802258598241 小时前
vue3源码解析:响应式机制
前端·vue.js
bo521001 小时前
浏览器渲染机制详解(包含渲染流程、树结构、异步js)
前端·面试·浏览器
时间会给答案scidag1 小时前
报错 400 和405解决方案
vue.js·spring boot
普通程序员1 小时前
Gemini CLI 新手安装与使用指南
前端·人工智能·后端
白杨木影子被拉长1 小时前
多状态映射不同样式(scss语法)
vue.js·uni-app
山有木兮木有枝_1 小时前
react受控模式和非受控模式(日历的实现)
前端·javascript·react.js
流口水的兔子1 小时前
作为一个新手,如果让你去用【微信小程序通过BLE实现与设备通讯】,你会怎么做,
前端·物联网·微信小程序