本章内容:
根据不同的路径 (锚点) ,显示不同的页面 (组件) ,不会刷新整个页面,,局部更新。
官方地址: https://router.vuejs.org/zh/
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
路由的出口,用于渲染当前路由模板,在含有导航链接的页面都与要进行路由出口,否则路由不起作用。
<router-link to="/Home">首页router-link>
<router-view>router-view>
导航链接
<router-link to="/Home">首页router-link>
标签属性
to (必选参数)
<router-link to="/Login">登录router-link>
tag
<router-link to="/Login" tag="strong">登录router-link>
// 创建`router`实例,传入`routes`配置。
let router = new VueRouter({
routes: [
{
path: "/index",
component: { // 每个路由中`component`的应该映射一个组件。
template: `首页
`
}
},
{
path: "/login",
component: {
template: `登录
`
}
}
]
})
new Vue({
el: "#app",
router // 将`router`挂载Vue实例中。
})
例如,我们有一个 login
组件,对于所有 ID 各不相同的用户,可以使用动态路由
将用户ID传入。
<div id="app">
<router-link to="/index">首页router-link>
<router-link to="/login/1/狗蛋/12345678">登录router-link>
<router-view/>
div>
// 创建`router`实例,传入`routes`信息,并定义动态路由。
let router = new VueRouter({
routes: [
{
path: "/index",
component: {
template: `首页
`
}
},
{
path: "/login/:userID/:userName/:passWord", // 绑定动态路径参数,以:进行绑定某些字段。
component: {
template: `{{$route.params}}
`
}
}
]
})
new Vue({
el: "#app",
router // 挂载路由
})
命名路由指的是在每一个路由配置上,都必须提供一个name
。
const Index = {
template: "..."
}
let router = new VueRouter({
routes: [
{
name: "index", // 提供当前路由配置上的`name`。
path: "/index",
component: Index
}
]
})
$router为VueRouter的实例, 是一个全局的路由对象。
$route是一个跳转的路由对象, 每一个路由都有route
对象, 是一个局部对象, 包含路由路径
携带的参数,以及查询字符携带
的参数。
<div id="app">
<router-link to="/index?userID=1&userName=大锤&passWord=1314521">首页router-link>
<router-link to="/login/33/狗蛋/5211314">登录router-link>
<router-view>router-view>
div>
let router = new VueRouter({
routes: [
{
path: "/index", // 查询参数不需要绑定。
component: {
template: `
登录
查询参数为:{{$route.query}}
`
}
},
{
path: "/login/:userID/:userName/:passWord", // 绑定动态路径参数,以:进行绑定某些字段。
component: {
template: `
登录
动态参数为:{{$route.params}}
`
}
}
]
})
new Vue({
el: "#app",
router // 挂载`router`实例
})
路由套路由,
内嵌套另一个
组件。
<div id="app">
<router-link to="/index">首页router-link>
<router-link to="/login">登录router-link>
<router-view>router-view>
div>
let router = new VueRouter({
routes: [
{
path: "/index",
component: {
template: `
首页
一入口
二入口
三入口
`
},
children: [ // 配置index的子路由。
{
path: "child1",
component: {
template: `一入口
`
}
},
{
path: "child2",
component: {
template: `二入口
`
}
},
{
path: "child3",
component: {
template: `三入口
`
}
}
]
},
{
path: "/login",
component: {
template: `登录
`
}
}
]
})
new Vue({
el: "#app",
router: router // 将配置的路由实例挂载Vue实例中。
})
例如我们访问/a
路由,重定向规定为/b
,则当访问/a
就会切换到/b
路由。
let router = new VueRouter({
routes: [
{
path: "/", // `/`表示根目录,`*`会匹配任意路由路径。
redirect: "/index" // 定义重定向,如果是根目录则自动重定向到`redirect`指定的路由。
},
{
path: "/index",
component: {
template: "首页
"
}
},
{
path: "/login",
component: {
template: "登录
"
}
}
]
})
在Vue实例内部,你可以通过$router
访问路由实例,因此你可以调用this.$router.push(...)
来导航到不同的路由。
或者使用 router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前 的 URL。
r o u t e r 和 r o u t e r 功 能 等 效 , 都 可 以 使 用 , 只 不 过 router和router功能等效,都可以使用,只不过 router和router功能等效,都可以使用,只不过router是router实例挂载Vue实例之后自动生成的对象。而router是构造函数。
// 实例化router
let router = new VueRouter({
routes: []
})
new Vue({
el: "#app",
methods: {
routerFn() {
// $router是`router`实例挂载到Vue中才有的实例对象。
this.$route.push(...);
// router实例。
router.push(...);
console.log(router === this.$router); // true,两种效果等效,都可使用。
}
},
router // 挂载`router`实例
})
push
该方法参数可以是一个字符串路径,或者是一个叙述地址的对象。例如:
// 字符串
this.$router.push("/index");
// 对象
this.$router.push({path: "index"});
// 命名路由,通过路由内配置的`name`值相互绑定,也可实现路由跳转。
this.$router.push({name: "index"});
// params动态路由
this.$router.push({name: "index", params: {id: 1} }); // -> {id: 1},可以通过$route.params获取。
// 查询参数,URL变成 /index?id=100
this.$router.push({name: "index", query: {id: 100} }); // -> {id: 100},可以通过$route.query获取。
如果提供了path,params就会被忽略,而query
不会被忽略。你可以提供路由的name
或手写完整的带有参数的path
。
const Id = '123';
// 提供了name,有效。
this.$router.push({name: "index", params: {Id} }); // -> /user/123
// 提供完整的`path`。
this.$router.push({ path: `/user/${Id}` }) // -> /user/123
// 这里的params不生效。
this.$router.push({path: "index", params: {Id} });
go
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
。
// 在浏览器记录中前进一步,等同于 history.forward()。
this.$router.go(1);
// 后退一步记录,等同于 history.back()。
this.$router.go(-1);
// 前进 3 步记录
this.$router.go(3);
// 如果 history 记录不够用,那就默默地失败呗
this.$router.go(-100);
this.$router.go(100);
是动态组件,所以我们可以使用
组件给它添加一些过渡效果。
<transition name="fade">
<router-view>router-view>
transition>
上面语法是给所有出口都进行了相同的过渡,如果想给每个路由模板添加各自的效果,可以在
上定义不同的name
。
const Bar = {
template: `
...
`
}
const Foo = {
template: `
...
`
}
vue-router
提供的导航守卫主要用来通过跳转或阻止跳转的方式守卫导航。记住参数或查询的改变并不会触发进入/离开的导航守卫
使用router.beforeEach
来注册一个全局前置守卫。
let router = new VueRouter({
routes: [
// ...
]
})
router.beforeEach((to, from, next) => {
// ...
})
同样也可以在vue中挂载的路由实例进行注册导航守卫。
let router = new VueRouter({
routes: [
// ...
]
})
new Vue({
el: "#app",
router, // ES6语法,与router: router等效
mounted() {
// 通过路由实例注册
this.$router.beforeEach((to, from, next) => {
// ...
})
}
})
每个守卫方法接受三个参数:
to
即将要进入的目标路由。
from
即将要离开的当前路由。
next
用于允许路由的切换,在路由切换中必须调用next()
, 否则钩子就不会被调用。
router.beforeEach((to, from, next) => {
next(); // 进行管道中的下一个钩子
next(false); // 中断当前的导航
next({path: "/login"}) // 链接到指定的路由,与`next("/login")`等效
})
使用router.afterEach
来注册一个全局后置守卫,但是它不接收next参数。
router.afterEach((to, from) => {
// ...
})
next回调
,后置守卫不接受next回调
。 在路由配置上直接定义beforeEnter
守卫
let router = new VueRouter({
routes: [
{
path: "/index",
component: Index,
beforeEnter(to, from, next) {
// ...
}
}
]
})
在路由组件内直接定义以下路由导航守卫 :
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`
}
}