官方解释:
vue
vue-router
提供的导航守卫主要用来经过跳转或取消的方式守卫导航。有多种机会植入路由导航过程当中:全局的, 单个路由独享的, 或者组件级的。vue-router
router.enterEach((to,from,next)>={浏览器
})app
to: Route
: 即将要进入的目标路由对象ui
对应参数this
fullPath:"/foo" hash:"" matched:[] meta:{} name:null params: __proto__:Object path:"/foo" query:{}
from: Route
: 当前导航正要离开的路由 (能够当成重定向使用)spa
ƒunction redirect(location) { return _this2.push(location); }
next: Function
: 必定要调用该方法来 resolve 这个钩子。执行效果依赖 next
方法的调用参数。code
next()
: 进行管道中的下一个钩子。若是所有钩子执行完了,则导航的状态就是 confirmed (确认的)。component
next(false)
: 中断当前的导航。若是浏览器的 URL 改变了(多是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from
路由对应的地址。router
next('/')
或者 next({ path: '/' })
: 跳转到一个不一样的地址。当前的导航被中断,而后进行一个新的导航。
next(error)
: (2.4.0+) 若是传入 next
的参数是一个 Error
实例,则导航会被终止且该错误会被传递给 router.onError()
注册过的回调。
<template> <div> <h2>About</h2> </div> </template>
components/Dashboard.vue
<template> <div> <h2>Dashboard</h2> <p>Yay you made it!</p> </div> </template>
components/login.vue
<template> <div> <h2>login</h2> </div> </template>
app.js
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) import About from './components/About.vue' import Dashboard from './components/Dashboard.vue' import Login from './components/Login.vue' const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/about', component: About }, { path: '/dashboard', component: Dashboard }, { path: '/login', component: Login,name:'Login' } ] }) router.beforeEach((to, from, next) => { const islogin=false console.log(to.path) console.log(!islogin&&to.path=='/login') if(!islogin&&to.path=='/login'){ next(); }else{ from({path:'login'}) } }) var vm=new Vue({ router, template: ` <div id="app"> <h1>Navigation Guards</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/about">/about</router-link></li> <li><router-link to="/dashboard">/dashboard</router-link></li> <li><router-link to="/login">/dashboard</router-link></li> </ul> <router-view class="view"></router-view> </div>
`
}).$mount('#app')
上图实现的直接连接判断是否登入时,未登陆的状况下直接跳转到登陆页
你能够在路由配置上直接定义 beforeEnter
守卫:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
举个例子
注意小组件如上面一个例子
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) import auth from './auth' import App from './components/App.vue' import About from './components/About.vue' import Dashboard from './components/Dashboard.vue' import Login from './components/Login.vue' function requireAuth (route, redirect, next) { if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: route.fullPath } }) } else { next() } } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ { path: '/about', component: About, beforeEnter: function (to, from) { const login = false if (!login) {
alert('111') from('/login') } } }, { path: '/dashboard', component: Dashboard }, { path: '/login', component: Login,name:'Login'} ] }) var vm=new Vue({ router, template: ` <div id="app"> <h1>Navigation Guards</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/about">/about</router-link></li> <li><router-link to="/dashboard">/dashboard</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')
具体实现的效果
beforeRouteEnter beforeRouteEnter 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` } }
举个例子1:
其余的组件的写法跟第一个同样的
beforeRouteEnter
// 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` 由于当守卫执行前,组件实例还没被建立,路由也不会改变
因此有写next()时,组件是不会展现的
about.vue
<template> <div> <h2>About</h2> <p>Yay you made it!</p> <div>{{num}}</div> </div> </template> <script> export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ console.log(to.path) }, beforeRouteLeave (to, from, next){ console.log(to.path); } } </script>
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) import auth from './auth' import About from './components/About.vue' import Dashboard from './components/Dashboard.vue' import Login from './components/Login.vue' function requireAuth (route, redirect, next) { if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: route.fullPath } }) } else { next() } } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ {path: '/about', component: About}, { path: '/dashboard', component: Dashboard }, { path: '/login', component: Login,name:'Login'} ] }) var vm=new Vue({ router, template: ` <div id="app"> <h1>Navigation Guards</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/about">/about</router-link></li> <li><router-link to="/dashboard">/dashboard</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')
实际实现效果:
举个例子2:
其余的组件的写法跟第一个同样的
components/About.vue
<template> <div> <h2>About</h2> <p>Yay you made it!</p> <div>{{num}}</div> </div> </template> <script> export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ console.log(to.path) next(vm=>{ vm.num=19; }) }, beforeRouteLeave (to, from, next){ console.log(to.path) } } </script>
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) import auth from './auth' import About from './components/About.vue' import Dashboard from './components/Dashboard.vue' import Login from './components/Login.vue' function requireAuth (route, redirect, next) { if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: route.fullPath } }) } else { next() } } const router = new VueRouter({ mode: 'history', base: __dirname, routes: [ {path: '/about', component: About}, { path: '/dashboard', component: Dashboard }, { path: '/login', component: Login,name:'Login'} ] }) var vm=new Vue({ router, template: ` <div id="app"> <h1>Navigation Guards</h1> <ul> <li><router-link to="/">/</router-link></li> <li><router-link to="/about">/about</router-link></li> <li><router-link to="/dashboard">/dashboard</router-link></li> </ul> <router-view class="view"></router-view> </div> ` }).$mount('#app')
实现效果:dashboard地址时,导航栏平没有发生变化,并不会离开
这里注意当我点击
若是想要离开的话,about.vue 这样改:只要在beforeRouteLeave在加入next()
<template> <div> <h2>About</h2> <p>Yay you made it!</p> <div>{{num}}</div> </div> </template> <script> export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ console.log(to.path) next(vm=>{ vm.num=19; }) }, beforeRouteLeave (to, from, next){ console.log(to.path); next(); } } </script>