六维教程

Vue3 路由基础

一个网站通常有”首页、列表、详情”等多个页面,传统网站里每个页面是一个独立的 HTML 文件,点开链接浏览器就整页刷新一次。

Vue 这类框架做的是 SPA(单页应用),整个站点只有一个 HTML 文件,切换页面只是替换页面组件,浏览器全程不刷新。

页面虽然没切换,但地址栏 URL 可是要跟着变的,不然浏览器的前进后退功能就会失效,也无法分享当前页面。

把”地址栏 URL”和”当前显示哪个组件”对应起来的机制,就是路由,它是 SPA 的地基,Vue 官方的路由方案是 Vue Router,当前主版本 4.x,完全贴合组合式 API。

安装

在项目根目录(有 package.jsonsrc/main.js 的目录)执行:

npm install vue-router@4

配置路由

路由的配置写在独立文件里,新建 src/router/index.js,然后要做两件事,写一张路由表(地址 → 组件的对应关系),再基于它创建一个 router 实例。

路由表本身不会干活,需要一个对象把”匹配地址、执行跳转、管理历史”这些能力组装起来,这个对象就是 router 实例,由 createRouter 创建。

它接收一个配置对象,两个核心选项是 routes(路由表)和 history(URL 的显示形式):

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/HomeView.vue'
import About from '../views/AboutView.vue'

// 路由表:一条记录就是一个"地址 → 组件"的对应
const routes = [
  { path: '/', component: Home },          // 访问 / 显示 Home 组件
  { path: '/about', component: About }     // 访问 /about 显示 About 组件
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

history 选项可以是 createWebHistorycreateWebHashHistory

  • createWebHashHistory:地址带 #/#/about),配置最简单,代价是 URL 不干净,一般用在无所谓SEO的场景。

  • createWebHistory:最常用的方式,也是默认选择。

createWebHistory()           // 部署在根目录
createWebHistory('/blog/')   // 部署在子路径,例如 https://a.com/blog/

router 本质是一个 Vue 插件,要在 main.js 里交给应用使用:

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

路由表配好了,路由匹配到的组件要渲染到页面哪个位置?这由 <router-view> 决定。

它是页面上的一块占位区域,当前路由对应哪个组件,哪个组件就被填进这里.

提供”从哪跳”的是 <router-link>,它最终渲染成一个 <a> 标签,但比原生链接聪明,它接管点击,拦截掉整页刷新,只通知路由去换组件,还自动给当前处于激活状态的链接加上 router-link-active 类,配一段 CSS 就能实现导航高亮,它的 to 属性就是目标地址,字符串或对象都行:

<!-- App.vue -->
<template>
  <nav>
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
  </nav>

  <!-- 路由匹配到的组件渲染到这里 -->
  <router-view />
</template>

打开首页看到首页组件,手动改成 /about 看到关于组件,中间没有任何刷新,这就是路由在干活。

切换路由时组件会重新创建吗

默认会,换一个路由,旧组件卸载、新组件挂载,行为跟动态组件一致。

直接感受是,切走再切回来,组件里的临时状态(比如填了一半的表单)会清空,这是正常行为。

想保留状态,Vue3 动态组件与缓存 里讲过的 KeepAlive 能解决,进阶篇也会再提到。

编程式导航

<router-link> 适合模板里的链接,但跳转不都从链接出发,按钮点击后跳转、登录成功跳首页、倒计时结束自动跳走,这些场景要在 JS 里主动跳转。

组合式 API 的思路是提供一个钩子函数,useRouter 就是这样的入口,在组件里调用就能拿到当前应用的 router 实例:

<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

const goAbout = () => {
  router.push('/about')        // 前进到 /about,历史栈记录
  // router.replace('/about')  // 替换当前记录,不留历史
  // router.back()             // 返回上一页
}
</script>

<template>
  <button @click="goAbout">去关于页</button>
</template>

router 实例上常用的跳转方法有三个,看各自用途。

router.push(to)

router.push(to) 是”前进并留痕”,往历史栈里压入一条新记录,用户能按返回键回到当前页。

to 可以是字符串 '/about',也可以是对象 { path: '/about' },对象写法在进阶篇展开。

它返回一个 Promise,导航完成或失败时落定,多数场景不用管:

router.push('/about')
router.push({ path: '/about' })

router.replace(to)

router.replace(to) 是”覆盖当前记录”,不留退路。

有些页面不希望用户”退回去”,比如登录成功后按返回键不该回到登录页,适合登录、支付这类页面:

router.replace('/login')   // 替换当前记录,返回键回不到这里

router.back()

router.back() 相当于浏览器返回键,由 router 提供,不依赖浏览器:

router.back()

获取当前路由

跳转之外,还常有”我现在在哪个地址”的需求,比如导航高亮当前菜单、详情页读取 URL 里的参数,useRoute 负责把当前匹配到的 route 对象交到组件手中。

route 对象记录当前地址的各种信息,常用属性有 pathnameparamsquery

<script setup>
import { useRoute } from 'vue-router'

const route = useRoute()
</script>
  • path 是当前路径,如 /about
  • name 是当前路由的名字,Vue3 路由进阶 讲命名路由时展开
  • paramsquery 分别对应路径参数和查询参数,动态路由取参数时用到,进阶篇展开

速查卡片

场景 写法
安装 npm install vue-router@4
定义路由 createRouter({ history, routes }) + app.use(router)
声明式跳转 <router-link to="/about">
出口 <router-view />
JS 跳转 useRouter()router.push('/x')
读取当前路由 useRoute()
刷新 404 History 模式需服务器 fallback(或用 hash 模式)
上一篇
Vue3 Teleport
下一篇
Vue3 路由进阶