目录
“导航”意为路由正在发生变化
♡ ‧₊˚ 全局守卫 ₊˚ ♡
全局守卫有全局前置守卫、全局后置守卫。
每个守卫方法接收三个参数:
to: Route
: 即将要进入的目标 路由对象from: Route
: 当前导航正要离开的路由next:是一个方法,一定要调用此方法来调用钩子,该方法接收参数为true时表示让钩子向下执行,接收参数为false时表示阻止钩子向下执行。
♡ ‧₊˚ 全局前置守卫 ₊˚ ♡
beforeEach(to,from, next)
当从一个路由跳转到另一个路由的时候触发,所以它是跳转前触发的,任何路由跳转都会触发。这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。
♡ ‧₊˚ 全局后置守卫 ₊˚ ♡
afterEach(to,from)
和beforeEach相反,它是在路由跳转完成后触发,它发生在beforeEach之后,beforeRouteEnter(组件内守卫)之前。全局后置守卫没有next方法,不需要调用next方法让路由向下执行。
♡ ‧₊˚路由独享的守卫 ₊˚ ♡
这个守卫是写在路由里面的,只有当进入这个路由时才会调用的,这些守卫与全局前置守卫的方法参数是一样的。
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
♡ ‧₊˚ 组件内的守卫 ₊˚ ♡
beforeRouteEnter
beforeRouteEnter(to, from, next) {
next();// 手动调用向下执行
next(fale);// 阻止路由向下执行
},
beforeRouteUpdate
beforeRouteUpdate(to, from, next) {
},
beforeRouteLeave
beforeRouteLeave(to, from, next) {
next()
}
面试问点:
组件内守卫的区别?
beforeRouteEnter的"this"无法访问组件实例,指向window。因为该
守卫是在导航确认前被调用的,而此时新组件还没被创建。
beforeRouteUpdate
与beforeRouteLeave的"this"可以访问当前组件实例。
但是,我们也可以通过next方法传递一个回调函数给beforeRouteEnter来访问组件实例
,在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
注意:
beforeRouteEnter
是支持给 next
传递回调的唯一守卫。因为对于 beforeRouteUpdate
和 beforeRouteLeave
来说,this
已经可用了,所以不支持传递回调,因为没有必要了。
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
beforeRouteLeave
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false)
来取消。
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
♡ ‧₊˚ 完整守卫流程 ₊˚ ♡
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。- 调用全局的
beforeEach
守卫。- 在重用的组件里调用
beforeRouteUpdate
守卫。- 在路由配置里调用
beforeEnter
。- 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。- 调用全局的
beforeResolve
守卫 (2.5+)。- 导航被确认。
- 调用全局的
afterEach
钩子。- 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
监听路由url地址栏变化
♡ ‧₊˚ created ₊˚ ♡
created(){
console.log(this.$route.params.xxx)
}
♡ ‧₊˚ watch ₊˚ ♡
watch:{
$route(to,from){
// to ---即将进入的路由
// from --上一个离开的路由
console.log(to.params)
}
}
♡ ‧₊˚ 组件内守卫 ₊˚ ♡
// 组件内守卫 组件更新触发钩子 user/2
beforeRouteUpdate(to,from,next){
console.log(to.params)
}
路由模式
♡ ‧₊˚ hash模式 ₊˚ ♡
vue的默认模式: hash
hash工作原理hashchange事件newRUL,oldURL
window.onhashchange = function (event) {
console.log(event);
}
我们在创建路由对象时设置路由模式
const router = new VueRouter({
mode: 'hash',
routes: [...]
})
♡ ‧₊˚ history模式 ₊˚ ♡
history工作原理利用是go back forward
const router = new VueRouter({
mode: 'history',
routes: [...]
})
当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id
,也好看!
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id
就会返回 404,这就不好看了。
所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html
页面,这个页面就是你 app 依赖的页面。
面试问点:
路由的两种模式及其区别?
- hash模式:会在路由路径携带#,不会请求服务器,工作原理是hashchange事件,支持低版本浏览器
- history模式:不会在路由路径携带#,会请求服务器,工作原理是go/back/ forward,是h5新增的api,不支持低版本浏览器。