官方解釋:
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>