Vue Router 怎么用?从基础到实战一次讲清楚
想在Vue项目里实现页面跳转、路由管理?Vue Router就是专门干这个的工具~这篇文章用问答形式,把Vue Router从基础配置到实际开发里的常见操作,一步步拆明白,新手也能跟着上手~
Vue Router 基础配置咋搞?
要让Vue项目能实现路由功能,得先完成「安装+配置+注入」这三步:
安装,打开终端,在Vue项目根目录执行对应的安装命令(Vue2和Vue3版本不同,按需选择):
- Vue3 项目:
npm install vue-router@4
- Vue2 项目:
npm install vue-router@3
接着创建路由配置文件,一般在项目 src
目录下新建 router
文件夹,再在里面创建 index.js
,以Vue3为例,index.js
的基础结构如下:
import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' // 引入首页组件 // 定义路由规则:每个对象对应一个页面的路径、名称、组件 const routes = [ { path: '/', // 访问根路径时 name: 'Home', // 路由的命名(可选,方便编程式跳转) component: Home // 要渲染的组件 }, { path: '/about', name: 'About', component: () => import('../views/About.vue') // 也可以用「懒加载」写法 } ] // 创建路由实例 const router = createRouter({ history: createWebHistory(), // Vue3的history模式(去掉url中的#);Vue2是 mode: 'history' routes // 传入上面定义的路由规则数组 }) export default router // 导出路由实例,供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) // 把路由注入Vue实例 app.mount('#app')
最后在页面中使用路由组件,打开 App.vue
(项目的根组件),用 <router-link>
实现跳转,用 <router-view>
显示匹配的组件:
<template> <div id="app"> <!-- 声明式跳转:点击“首页”跳转到根路径 --> <router-link to="/">首页</router-link> <!-- 点击“关于我们”跳转到/about --> <router-link to="/about">关于我们</router-link> <!-- 路由匹配到的组件,会渲染到<router-view>里 --> <router-view></router-view> </div> </template>
怎么实现页面之间的路由跳转?
Vue Router提供了「声明式」和「编程式」两种跳转方式,场景不同选不同的:
声明式跳转:用 <router-link>
适合在模板里直接写跳转(比如导航栏、菜单),核心是 to
属性,支持两种传值方式:
- 字符串路径:直接写目标路径,如
<router-link to="/about">关于我们</router-link>
。 - 对象格式:想传参或用「命名路由」时用,示例:
<router-link :to="{ name: 'User', params: { id: 123 }}">用户页</router-link>
这里的
name
对应路由配置里的name
字段,params
用来传路径参数(下文会讲动态路由)。
如果想跳转后替换历史记录(比如防止回退到上一页),可以加 replace
属性:
<router-link to="/" replace>首页</router-link>
编程式跳转:用 this.$router
适合在方法里触发跳转(比如点击按钮后判断再跳转),常用API有这几个:
this.$router.push()
:跳转到新页面,历史记录新增一条(能回退),示例:methods: { goProfile() { // 跳转到/profile,并带查询参数?tab=setting this.$router.push({ path: '/profile', query: { tab: 'setting' } }) } }
this.$router.replace()
:跳转时替换当前历史记录(不能回退到上一个路由),比如支付成功后,用replace
跳转到结果页,避免用户回退再支付:this.$router.replace('/pay/success')
this.$router.go(n)
:控制历史记录前进/后退,n
是数字。this.$router.go(-1)
就是回退到上一页,和浏览器「返回」按钮效果一样。
动态路由和参数传递咋处理?
开发中经常需要「根据不同ID展示不同内容」(比如用户详情页 /user/1
、商品详情页 /goods/2024
),这就得用动态路由 + 参数传递。
步骤1:配置动态路由规则
在 router/index.js
里,给 path
加动态参数(用 标记):
{ path: '/user/:id', // :id 是动态参数,不同用户ID对应不同路径 name: 'User', component: User }
步骤2:传递 & 接收参数
参数传递分两种思路:路径参数(params)和查询参数(query),用法和场景不同:
路径参数(params)
参数写在路径里(如 /user/123
),用 params
传值。
-
跳转时:可以用「命名路由+params」,也可以直接写路径:
// 方式1:命名路由 + params this.$router.push({ name: 'User', params: { id: 123 } }) // 方式2:直接写路径 this.$router.push('/user/123')
-
接收时:在组件里用
this.$route.params.id
获取(注意是$route
不是$router
,$route
是当前路由信息)。
查询参数(query)
参数跟在url后面(如 /user?name=小明
),用 query
传值。
- 跳转时:
this.$router.push({ path: '/user', query: { name: '小明' } })
- 接收时:在组件里用
this.$route.query.name
获取。
区别:路径参数(params)如果不在 path
里定义,刷新页面会丢失;查询参数(query)会显示在url上,刷新也能保留~
嵌套路由(子路由)怎么设置?
做后台管理系统时,经常遇到「一级页面套二级页面」的情况(仪表盘」页面里,还要分「数据概览」「访问分析」等子页面),这时候用嵌套路由。
步骤1:配置子路由规则
在父路由的配置里,加 children
数组,每个子路由是一个对象:
{ path: '/dashboard', // 父路由路径 name: 'Dashboard', component: Dashboard, // 父组件(里面要放<router-view>显示子组件) children: [ { path: 'overview', // 子路由路径,完整路径是 /dashboard/overview(不用加 /) name: 'Overview', component: Overview }, { path: 'analysis', name: 'Analysis', component: Analysis } ] }
步骤2:父组件里放 <router-view>
打开父组件(Dashboard.vue
),在需要显示子组件的位置加 <router-view>
:
<template> <div class="dashboard"> <aside>侧边栏(固定内容)</aside> <main> <!-- 子组件会渲染到这里 --> <router-view></router-view> </main> </div> </template>
这样,访问 /dashboard/overview
时,Dashboard
组件会渲染,Overview
组件会渲染到父组件的 <router-view>
里,实现「父页面套子页面」的效果~
路由守卫有啥用?怎么用?
路由守卫就像「路由的门卫」,能在跳转前/后执行逻辑(比如判断用户是否登录、权限够不够、页面离开前保存表单数据……)。
Vue Router的守卫分三类:全局守卫、路由独享守卫、组件内守卫。
全局守卫:控制所有路由跳转
在 router/index.js
里,用 router.beforeEach
拦截所有路由跳转:
router.beforeEach((to, from, next) => { // to:要跳转到的目标路由;from:从哪个路由来;next:决定是否放行 if (to.meta.requiresAuth) { // 假设路由配置里加了 meta 标记“需要权限” if (isLogin()) { // 自定义函数,判断用户是否登录 next() // 登录了,放行 } else { next('/login') // 没登录,跳转到登录页 } } else { next() // 不需要权限,直接放行 } })
还可以用 router.afterEach
,在路由跳转之后执行(比如修改页面标题):
router.afterEach((to) => { document.title = to.meta.title || '默认标题' })
路由独享守卫:只拦截某个路由
在具体的路由配置里,加 beforeEnter
(只对当前路由生效):
{ path: '/profile', name: 'Profile', component: Profile, beforeEnter: (to, from, next) => { // 逻辑和全局守卫类似,只对 /profile 路由生效 if (isLogin()) { next() } else { next('/login') } } }
组件内守卫:组件里自己控制
在组件的 <script>
里写,常用的有三种:
beforeRouteEnter
:进入该组件的路由之前触发(此时组件实例还没创建,this
是undefined
),如果要访问组件数据,用next(vm => { vm.xxx })
。beforeRouteUpdate
:路由参数变化时触发(比如从/user/1
跳到/user/2
,组件复用的情况)。beforeRouteLeave
:离开该组件的路由之前触发(比如表单没保存,阻止跳转)。
举个「表单离开前确认」的例子:
export default { name: 'EditForm', data() { return { formDirty: false } // 标记表单是否修改过 }, beforeRouteLeave(to, from, next) { if (this.formDirty) { const confirm = window.confirm('表单没保存,确定离开?') if (confirm) { next() // 确定就放行 } else { next(false) // 取消就留在当前页 } } else { next() // 没修改过,直接放行 } } }
路由懒加载怎么配置?
如果项目页面很多,全打包成一个大文件,首屏加载会很慢。路由懒加载能把每个页面拆成小文件,访问时再加载,从而优化性能。
配置很简单:把原来的 import Home from '../views/Home.vue'
改成动态 import
形式:
// 动态import:只有访问该路由时,才会加载对应的组件代码 const Home = () => import('../views/Home.vue') // 路由配置里直接用 { path: '/', name: 'Home', component: Home }
404页面咋配置?
用户访问了不存在的路径,得显示友好的404页面,关键是路由的匹配顺序(Vue Router是「从上到下匹配路由」,前面的规则没匹配到,才会走404):
- 先创建
NotFound
组件(views/NotFound.vue
),写好404样式。 - 在
router/index.js
的路由规则最后,加一个「通配符路由」:{ // Vue3 写法:匹配所有未定义的路径(包括多级路径,如 /a/b/c) path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }
// Vue2 写法:path: '*'(只能匹配一级路径,如 /a)
<p>看完这些,Vue Router的核心用法基本覆盖啦~从基础配置到跳转、传参、嵌套、守卫、性能优化,再到404处理,都是项目里高频用到的知识点,实际开发时,把这些技巧组合起来,就能灵活实现复杂的路由逻辑~要是还有具体场景搞不定,评论区喊我,咱再细拆~</p>
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。