vue-router
是Vue.js官方的路由插件,它适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们
编写单页面的步骤
1.创建组件:创建单页面应用需要渲染的组件
var Home = Vue.extend({
template: '<div><h1>Home</h1><p>{{msg}}</p></div>',
data: function() {
return {
msg: 'Hello, vue router!'
}
}
})
var About = Vue.extend({
template: '<div><h1>About</h1><p>This is the tutorial about vue-router.</p></div>'
})
2.创建路由:创建VueRouter实例
var router = new VueRouter()
3.映射路由:调用VueRouter实例的map方法
router.map({
'/home': { component: Home },
'/about': { component: About }
})
4.使用v-link指令
to表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。
active-class是vue-router模块的router-link组件中的属性,用来做选中样式的切换
使用active-class有两种方法:
1、直接在路由js文件中配置linkActiveClass
export default new Router({
linkActiveClass: 'active',
})
2、在router-link中写入active-class
<router-link to="/home" class="menu-home" active-class="active">首页</router-link>
<div class="list-group">
<a class="list-group-item" v-link="{ path: '/home'}">Home</a>
<a class="list-group-item" v-link="{ path: '/about'}">About</a>
</div>
5.使用<router-view>标签
<router-view></router-view>
6.启动路由:调用VueRouter实例的start方法
var App = Vue.extend({})
router.start(App, '#app')
router.redirect
应用在首次运行时右侧是一片空白,应用通常都会有一个首页,例如:Home页。
使用router.redirect方法将根路径重定向到/home路径:
router.redirect({
'/': '/home'
})
router.redirect方法用于为路由器定义全局的重定向规则,全局的重定向会在匹配当前路径之前执行。
执行过程
当用户点击v-link指令元素时
1.vue-router首先会去查找v-link指令的路由映射
2.然后根据路由映射找到匹配的组件
3.最后将组件渲染到标签
动态路由
1.前端这边把路由写好,登录的时候根据用户的角色权限来动态展示路由,(前端控制路由)
2.后台传来当前用户对应权限的路由表,前端通过调接口拿到后处理(后端处理路由)
在 vue-router 的路由路径中使用『动态路径参数』(dynamic segment)来达到这个效果:在静态路由名称前加冒号
{
path:"/two:id",
component:{template:"#b"},
},
嵌套路由
实现嵌套路由有两个要点:
在组件内部使用<router-view>标签
在路由器对象中给组件定义子路由
路由对象
在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,并且当路由切换时,路由对象会被更新。
路由对象暴露了以下属性:
$route.path
字符串,等于当前路由对象的路径,会被解析为绝对路径,如 “/home/news” 。
$route.params
对象,包含路由中的动态片段和全匹配片段的键值对
($route.params.id)获取传过来的动态参数
$route.query
对象,包含路由中查询参数的键值对。例如,对于 /home/news/detail/01?favorite=yes ,会得到$route.query.favorite == ‘yes’ 。
$route.router
路由规则所属的路由器(以及其所属的组件)。
$route.matched
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
$route.name
当前路径的名字,如果没有使用具名路径,则名字为空。
vue-router的导航钩子
正如其名,vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式可以在路由导航发生时执行钩子:
1.全局的
当一个导航触发时,全局导航钩子主要有两种钩子:前置守卫(beforeEach)、后置钩子(afterEach).全局的 before 钩子按照创建顺序调用。钩子是异步解析执行,此时导航在所有钩子 resolve 完之前一直处于 等待中。
注册一个全局前置守卫:
const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
// do someting
});
这三个参数 to 、from 、next 分别的作用:
to: Route,代表要进入的目标,它是一个路由对象
from: Route,代表当前正要离开的路由,同样也是一个路由对象
next: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数。next():进入管道中的下一个钩子,如果全部的钩子执行完了,则导航的状态就是 confirmed(确认的)
next(false):这代表中断掉当前的导航,即 to 代表的路由对象不会进入,被中断,此时该表 URL 地址会被重置到 from 路由对应的地址.next(‘/’) 和 next({path: ‘/’}):在中断掉当前导航的同时,跳转到一个不同的地址.next(error):如果传入参数是一个 Error 实例,那么导航被终止的同时会将错误传递给 router.onError() 注册过的回调
router.afterEach((to, from) => {
// do someting
});
不同于前置守卫,后置钩子并没有 next 函数,也不会改变导航本身
2.单个路由独享的
顾名思义,即单个路由独享的导航钩子,它是在路由配置上直接进行定义的: beforeEnter
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
},
beforeEnter: (route) => {
// ... } } ]});
3.组件级的
组件内的导航钩子主要有这三种:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是直接在路由组件内部直接进行定义的
const File = {
template: `<div>This is file</div>`,
beforeRouteEnter(to, from, next) {
// do someting
// 在渲染该组件的对应路由被 confirm 前调用
},
beforeRouteUpdate(to, from, next) {
// do someting
// 在当前路由改变,但是依然渲染该组件是调用
},
beforeRouteLeave(to, from ,next) {
// do someting
// 导航离开该组件的对应路由时被调用
}}
完整的导航解析流程:
导航被触发
在失活的组件里调用离开守卫
调用全局的 beforeEach 守卫
在重用的组件里调用 beforeRouteUpdate 守卫
在路由配置里调用 beforEnter
解析异步路由组件
在被激活的组件里调用 beforeRouteEnter
调用全局的 beforeResolve 守卫
导航被确认
调用全局的 afterEach 钩子
触发 DOM 更新
在创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数