vue 中的路由,路由嵌套以及钩子函数
什么是路由呢?
在网络原理中路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程。
而在web开发中,路由就是URL到函数的映射。
使用Vue开发项目,我们需要使用路由将组件(components)映射到(routes),然后在需要的地方进行使用渲染。
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
对于路由的使用就不免提到router-link
和 router-view
了。
1、router-link可以实现路由跳转
简单说下它的两种写法:
<router-link :to="{ path: '/hello', component: HelloWorld }">hello</router-link>
<router-link :to="{ path: '/user/useradd' }">user</router-link>
(1)有component参数时优先router-link中配置的component,没有时从js中配置取
(2)path参数至关重要,灵活所在,/user/useradd 实际匹配了两个组件,分别是user和useradd
路由跳转还有另外一种方式:$router.push()
调用的方法:
// 字符串
this.$router.push('home')
// 对象
this.$router.push({ path: 'home' })
// 命名的路由
this.$router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=private
this.$router.push({ path: 'register', query: { plan: 'private' }})
2、router-view则是用来渲染通过路由映射过来的组件,当路径更改时, 中的内容也会发生更改
<router-link :to="{ path: '/hello', component: HelloWorld }">hello</router-link>
<router-link :to="{ path: '/user/useradd' }">user</router-link>
<router-view/>
当前主要应用于单页面中,与router-link配合,渲染router-link 映射过来的组件。
路由嵌套
实际生活中的应用界面,通常由多层嵌套的组件组合而成。
每一个路由都可以配置子路由,这就是路由嵌套。
比如,每一个应用的Home页都可以跳转到登录页和注册页,把登录、注册设置成Home路由的子路由。
// 定义一个路由
const routes = [
{ path: '/', redirect: '/home' },
{
path: '/home',
component: Home,
children:[
{ path: '/home/login', component: Login},
{ path: '/home/reg', component: Reg}
]
},
{ path: '/news', component: News}
]
任何子路由都是在其父路由的组件中切换显示,不管是多少层的路由嵌套,都是这样的理解,所以父路由需要有以下两点,二者缺一不可
- 有组件引用
- 组件中有router-view组件
钩子函数
导航和钩子函数:
导航:路由正在发生改变 、
钩子函数:在路由切换的不同阶段调用不同的节点函数
两者关系:
钩子函数 —> 导航 : 钩子函数 主要用来拦截导航,让它完成跳转或取消,在导航的不同阶段来执行不同的函数,最后钩子函数的执行结果会告诉导航怎么做。。
导航 —> 钩子函数 : 导航在所有钩子 resolve 完之前一直处于等待中,等待钩子函数告诉它下一步该怎么做。用
next()
来指定。
有多种方式可以在路由导航发生时执行钩子:全局的、单个路由独享的、或者组件级的。
一、全局钩子函数
//可以通过router.beforeEach创建一个全局的before钩子
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
//也可以创建全局的after钩子,不过after钩子没有next(),没有办法改变导航
二、单个路由独享的钩子函数
// 可以在路由配置上直接定义 beforeEnter 钩子
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
// 这些钩子与全局 before 钩子的方法参数是一样的
三、组件内的钩子函数
// 可以在路由组件内直接定义以下路由导航钩子
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// ...
},
beforeRouteUpdate (to, from, next) {
// ...
},
beforeRouteLeave (to, from, next) {
// ...
}
}
可以看到创建的before钩子都拥有三个参数:
to:router即将进入的路由对象。
from:当前导航即将离开的路由。
next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
而after钩子函数是不用传next()函数的。
我们一般在权限验证和页面找不到的时候使用,但必须是全局钩子。