ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【vue2】路由之 Vue Router

2026/9/11 8:23:55 拓冰建站 浏览量
【vue2】路由之 Vue Router

文章目录

  • 一、安装
  • 二、基础使用
    • 1、简单的示例
    • 2、动态路由
      • 2.1 定义动态路径参数
      • 2.2 获取动态路径的参数
      • 2.3 捕获所有路由
    • 3、嵌套路由
    • 4、编程式的导航
      • 4.1 router.push
      • 4.2 router.replace
      • 4.3 router.go(n)
    • 5、命名路由
    • 6、重定向
  • 三、进阶
    • 1、导航守卫
      • 1.1 全局前置守卫
      • 1.2 全局后置钩子
      • 1.3 路由独享的守卫
      • 1.4 组件内的守卫
      • 完整的导航解析流程
    • 2、路由懒加载

一、安装

NPM
注意:vue2中需使用 v.3x 版本

npm install vue-router@3.0.0 --save

vue-router v3.x 文档:文档链接

二、基础使用

1、简单的示例

src/main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = {template: '<div>Foo</div>'
}
const Bar = {template: '<div>Bar</div>'
}// 2. 定义路由
// 每个路由应该映射一个组件
const routes = [{ path: '/foo', component: Foo },{ path: '/bar', component: Bar }
]// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({routes
})// 4. 通过 Vue.use() 明确地安装路由功能
Vue.use(VueRouter);// 5. 创建和挂载根实例。
// 通过 router 配置参数注入路由,让整个应用都有路由功能
new Vue({router,render: h => h(App),
}).$mount('#app')

src/App.vue

<template><div id="app"><p><!-- 使用 router-link 组件来导航. --><!-- 通过传入 `to` 属性指定链接. --><!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --><router-link to="/foo">Foo</router-link><br /><router-link to="/bar">Bar</router-link></p><!-- 路由出口,路由匹配到的组件将渲染在这里 --><router-view></router-view></div>
</template><script>
export default {name: "App",components: {},
};
</script>

2、动态路由

2.1 定义动态路径参数

动态路径参数以冒号开头

const User = {template: '<div>User</div>'
}const router = new VueRouter({routes: [// 动态路径参数 以冒号开头{ path: '/user/:id', component: User }]
})

现在像 /user/123 和 /user/456 都将映射到相同的路由

2.2 获取动态路径的参数

当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用

const User = {template: '<div>User {{ $route.params.id }}</div>'
}

可以通过 $route.params 查看所有的参数信息
$route 对象还提供了其它有用的信息

const User = {template: '<div>User {{ $route.params.id }}</div>',created: function () {console.log(this.$route)}
}

当路由是 /user/101 时,$route 示例:
在这里插入图片描述

2.3 捕获所有路由

可以使用通配符 (*):

{// 会匹配所有路径path: '*'
}
{// 会匹配以 `/user-` 开头的任意路径path: '/user-*'
}

3、嵌套路由

要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:
src/main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'import UserView from './components/UserView.vue'
import FooView from './components/FooView.vue'
import BarView from './components/BarView.vue'const routes = [{path: '/user',component: UserView,children: [{// 当 /user/foo 匹配成功,// FooView 会被渲染在 User 的 <router-view> 中path: 'foo',component: FooView},{// 当 /user/bar 匹配成功,// BarView 会被渲染在 User 的 <router-view> 中path: 'bar',component: BarView},]},
]const router = new VueRouter({routes
})Vue.use(VueRouter);new Vue({router,render: h => h(App),
}).$mount('#app')

顶层 <router-view> 出口,App.vue

<template><div id="app"><p><router-link to="/user/foo">Foo</router-link><br /><router-link to="/user/bar">Bar</router-link><br /></p><!-- 这个是顶层的 router-view --><router-view></router-view></div>
</template><script>
export default {name: "App",components: {},
};
</script>

组件同样可以包含自己的嵌套 <router-view>
组件 UserView.vue

<template><div class="user"><h2>User</h2><router-view></router-view></div>
</template>

组件 BarView.vue

<template><div>bar</div>
</template>

组件 FooView.vue

<template><div>foo</div>
</template>

要注意,以 / 开头的嵌套路径会被当作根路径

4、编程式的导航

4.1 router.push

这个方法会向 history 栈添加一个新的记录
代码实现路由跳转:

router.push(location, onComplete?, onAbort?)
声明式编程式
<router-link :to="..." >router.push(...)

该方法的参数可以是一个字符串路径,或者一个描述地址的对象,示例:

<template><div id="app"><div><button @click="routeUser">字符串跳转user</button><button @click="routeFoo">对象跳转foo</button><button @click="routeBarParams">对象跳转带参数Params</button><button @click="routeBarQuery">对象跳转带参数Query</button></div><!-- 这个是顶层的 router-view --><router-view></router-view></div>
</template><script>
export default {name: "App",components: {},methods: {routeUser() {// 字符串this.$router.push("/user");},routeFoo() {// 对象this.$router.push({path: "/foo"});},routeBarParams() {// 命名的路由(带name属性)this.$router.push({ name: 'bar', params: { id: '123' }})},routeBarQuery() {// 带查询参数,变成 /bar?id=456this.$router.push({ path: '/bar', query: { id: '456' }})// 注意:如果提供了 path,params 会被忽略// 下面的 params 不生效// this.$router.push({ path: '/bar', params: { id }}) // -> /user},},
};
</script>

4.2 router.replace

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录

router.replace(location, onComplete?, onAbort?)
声明式编程式
<router-link :to="..." replace>router.replace(...)

4.3 router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
示例:

// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)// 后退一步记录,等同于 history.back()
router.go(-1)// 前进 3 步记录
router.go(3)

5、命名路由

可以在创建 Router 实例的时候,在 routes 配置中使用 name 给某个路由设置名称:

const router = new VueRouter({routes: [{path: '/user/:userId',name: 'user',component: User}]
})

6、重定向

重定向也是通过 routes 配置来完成,使用 redirect
下面例子是从 /a 重定向到 /b:

const router = new VueRouter({routes: [{ path: '/a', redirect: '/b' }]
})

三、进阶

1、导航守卫

1.1 全局前置守卫

使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })router.beforeEach((to, from, next) => {// ...
})

每个守卫方法接收三个参数:

  • to: Route: 即将要进入的目标 路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
    • next(): 进行管道中的下一个钩子
    • next(false): 中断当前的导航
    • next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址

确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

身份时重定向到 /login 的示例:

router.beforeEach((to, from, next) => {if (to.name !== 'Login' && !isAuthenticated) {next({ name: 'Login' })} else {next()}
})

1.2 全局后置钩子

也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => {// ...
})

1.3 路由独享的守卫

可以在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]
})

1.4 组件内的守卫

可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

const Foo = {template: `...`,beforeRouteEnter(to, from, next) {// 在渲染该组件的对应路由被 confirm 前调用// 不!能!获取组件实例 `this`// 因为当守卫执行前,组件实例还没被创建},beforeRouteUpdate(to, from, next) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 `this`},beforeRouteLeave(to, from, next) {// 导航离开该组件的对应路由时调用// 可以访问组件实例 `this`}
}

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 10.调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入

2、路由懒加载

就是当路由被访问的时候才加载对应的组件
示例:

const Foo = () => import('./Foo.vue')const router = new VueRouter({routes: [{ path: '/foo', component: Foo }]
})