vue-router導航守衛

導航守衛

官方解釋: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() 註冊過的回調。

 

案例:
components/About.vue
<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>

 

相關文章
相關標籤/搜索