NPM
注意:vue2中需使用 v.3x 版本
npm install [email protected] --save
vue-router v3.x 文档:文档链接
src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = {
template: 'Foo'
}
const Bar = {
template: 'Bar'
}
// 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="/foo">Foorouter-link><br />
<router-link to="/bar">Barrouter-link>
p>
<router-view>router-view>
div>
template>
<script>
export default {
name: "App",
components: {},
};
script>
动态路径参数以冒号开头
const User = {
template: 'User'
}
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
现在像 /user/123 和 /user/456 都将映射到相同的路由
当匹配到一个路由时,参数值会被设置到 this.$route.params
,可以在每个组件内使用
const User = {
template: 'User {{ $route.params.id }}'
}
可以通过 $route.params
查看所有的参数信息
$route
对象还提供了其它有用的信息
const User = {
template: 'User {{ $route.params.id }}',
created: function () {
console.log(this.$route)
}
}
可以使用通配符 (*):
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
要在嵌套的出口中渲染组件,需要在 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 的 中
path: 'foo',
component: FooView
},
{
// 当 /user/bar 匹配成功,
// BarView 会被渲染在 User 的 中
path: 'bar',
component: BarView
},
]
},
]
const router = new VueRouter({
routes
})
Vue.use(VueRouter);
new Vue({
router,
render: h => h(App),
}).$mount('#app')
顶层
出口,App.vue
<template>
<div id="app">
<p>
<router-link to="/user/foo">Foorouter-link><br />
<router-link to="/user/bar">Barrouter-link><br />
p>
<router-view>router-view>
div>
template>
<script>
export default {
name: "App",
components: {},
};
script>
组件同样可以包含自己的嵌套
组件 UserView.vue
<template>
<div class="user">
<h2>Userh2>
<router-view>router-view>
div>
template>
组件 BarView.vue
<template>
<div>
bar
div>
template>
组件 FooView.vue
<template>
<div>
foo
div>
template>
要注意,以 / 开头的嵌套路径会被当作根路径
这个方法会向 history 栈添加一个新的记录
代码实现路由跳转:
router.push(location, onComplete?, onAbort?)
声明式 | 编程式 |
---|---|
|
router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象,示例:
<template>
<div id="app">
<div>
<button @click="routeUser">字符串跳转userbutton>
<button @click="routeFoo">对象跳转foobutton>
<button @click="routeBarParams">对象跳转带参数Paramsbutton>
<button @click="routeBarQuery">对象跳转带参数Querybutton>
div>
<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=456
this.$router.push({ path: '/bar', query: { id: '456' }})
// 注意:如果提供了 path,params 会被忽略
// 下面的 params 不生效
// this.$router.push({ path: '/bar', params: { id }}) // -> /user
},
},
};
script>
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录
router.replace(location, onComplete?, onAbort?)
声明式 | 编程式 |
---|---|
|
router.replace(...) |
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
示例:
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
可以在创建 Router 实例的时候,在 routes 配置中使用 name
给某个路由设置名称:
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
重定向也是通过 routes 配置来完成,使用 redirect
下面例子是从 /a 重定向到 /b:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
使用 router.beforeEach
注册一个全局前置守卫:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
每个守卫方法接收三个参数:
确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错
身份时重定向到 /login 的示例:
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) {
next({ name: 'Login' })
} else {
next()
}
})
也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to, from) => {
// ...
})
可以在路由配置上直接定义 beforeEnter 守卫:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
可以在路由组件内直接定义以下路由导航守卫:
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`
}
}
就是当路由被访问的时候才加载对应的组件
示例:
const Foo = () => import('./Foo.vue')
const router = new VueRouter({
routes: [{ path: '/foo', component: Foo }]
})