1、路由基础:SPA概念、前端路由原理、Vue Router 4.x安装与配置
1.1 什么是SPA?为什么我们需要它?
SPA,全称是Single Page Application,单页应用。说白了,就是整个网站只有一个HTML页面。
你想想看,传统的网站,点一个链接,整个页面刷新一次。白屏、闪烁、等待...用户体验很差。SPA就不一样了——页面切换时,只有内容区域变化,头部、底部、侧边栏这些公共部分纹丝不动。
我个人习惯把SPA比作「换书不换书架」。书架就是那个唯一的HTML页面,书就是不同的内容模块。你换书的时候,书架不会动,对吧?
我在项目中遇到过不少团队,刚转SPA时总想用传统方式跳转。结果呢?页面闪烁、状态丢失,折腾半天又改回来。嗯,这里要注意:SPA的核心思维是「组件切换」,不是「页面跳转」。
1.2 前端路由原理:Hash模式 vs History模式
SPA只有一个页面,那怎么实现「看起来像多个页面」的效果?答案就是前端路由。
前端路由有两种主流实现方式:Hash模式和History模式。我一个个说。
1.2.1 Hash模式
Hash模式利用URL中的#符号。比如:http://example.com/#/home。这个#/home就是hash值。
为什么它能工作?因为hash变化不会触发页面刷新,但会触发hashchange事件。我们监听这个事件,就能知道用户想去哪个页面。
我曾经踩过一个坑:某个项目上线后,用户反馈分享链接打不开。排查半天,发现是hash模式下的URL,后端没做处理,直接返回404。其实hash模式根本不需要后端配合,问题出在分享时URL被截断了。从那以后,我建议团队用History模式。
// Hash模式监听示例
window.addEventListener('hashchange', () => {
const hash = window.location.hash.slice(1) // 获取 # 后面的路径
console.log('当前路由:', hash)
// 根据hash渲染对应组件
})
1.2.2 History模式
History模式用的是HTML5的History API。它没有#,URL看起来和传统网站一模一样:http://example.com/home。
原理是通过pushState和replaceState改变URL,同时监听popstate事件。注意,popstate只会在浏览器前进后退时触发,pushState不会触发它。
/home 或刷新页面时,后端必须返回index.html,否则会404。我见过太多团队上线后才发现这个问题。
// History模式监听示例
window.addEventListener('popstate', () => {
const path = window.location.pathname
console.log('当前路径:', path)
// 根据path渲染对应组件
})
1.3 Vue Router 4.x:安装与配置
好了,原理讲完了。现在咱们动手,把Vue Router 4.x装起来。
1.3.1 安装
Vue Router 4.x对应Vue 3。如果你还在用Vue 2,那是Vue Router 3.x,别搞混了。
# npm安装
npm install vue-router@4
# 或者yarn
yarn add vue-router@4
安装完成后,我们创建一个路由配置文件。我个人习惯放在src/router/index.js。
1.3.2 基础配置
先看一个最简配置。假设我们有三个页面:首页、关于页、用户页。
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import User from '../views/User.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user/:id',
name: 'User',
component: User
}
]
const router = createRouter({
history: createWebHistory(), // 使用History模式
routes
})
export default router
这里有几个关键点:
createRouter:创建路由实例createWebHistory:启用History模式。想用Hash模式就换成createWebHashHistorypath: '/user/:id':动态路由,:id是参数占位符
name属性。后期用router.push({ name: 'User', params: { id: 1 } })跳转,比拼字符串路径更安全、更易维护。
1.3.3 在main.js中注册
配置好路由后,需要在Vue应用入口注册。
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router) // 注册路由插件
app.mount('#app')
注意顺序:先app.use(router),再app.mount('#app')。我曾经反过来写过,结果路由没生效,排查了半天才发现是注册顺序的问题。
1.3.4 在模板中使用
路由注册完成后,在App.vue里放两个核心组件:
<template>
<div id="app">
<!-- 导航链接 -->
<nav>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-link :to="{ name: 'User', params: { id: 1 } }">用户1</router-link>
</nav>
<!-- 路由出口:匹配到的组件会渲染在这里 -->
<router-view />
</div>
</template>
<router-link>最终会被渲染成<a>标签,但它会阻止默认跳转,改用路由切换。<router-view>就是组件渲染的位置,相当于一个占位符。
1.4 动态路由:为什么需要它?
你想想看,一个用户中心页面,每个用户的ID不同。难道要为每个用户写一个路由?当然不。动态路由就是干这个的。
动态路由的核心是路径参数。比如/user/:id,:id就是参数。当用户访问/user/123时,id的值就是123。
在组件中获取参数:
// User.vue
<template>
<div>用户ID:{{ $route.params.id }}</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log('用户ID:', route.params.id)
</script>
useRoute()获取当前路由信息。不要用this.$route,那是Options API的写法。Composition API里用useRoute和useRouter。
1.5 避坑指南:我踩过的那些坑
讲几个我实际项目中遇到的坑,希望能帮你少走弯路。
- 路由重复注册: 有一次我在多个文件中都调用了
app.use(router),结果路由重复,页面渲染异常。记住:只注册一次。 - History模式部署404: 前面说过,后端必须配置。Nginx的配置示例:
try_files $uri $uri/ /index.html; - 动态路由参数变化不刷新: 从
/user/1跳到/user/2,组件默认复用,不会重新创建。需要用watch监听route.params的变化。
// 监听路由参数变化
import { watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
watch(() => route.params.id, (newId, oldId) => {
console.log(`用户ID从 ${oldId} 变为 ${newId}`)
// 重新获取数据
})
1.6 小结
这一章我们聊了SPA的概念、前端路由的两种实现方式,以及Vue Router 4.x的安装配置。说白了,路由就是SPA的「交通系统」——它决定了用户从哪来、到哪去、怎么走。
下一章,我们会深入动态路由的进阶用法,包括嵌套路由、命名视图、路由守卫等。嗯,这些才是真正实战中天天用的东西。
记住:路由配置越清晰,项目后期维护越轻松。别偷懒,每个路由都加上name,路径命名规范统一。这是我个人的血泪教训。