vue學習-vue router路由配置,元信息meta的使用-登錄攔截驗證

路由基本配置

1.在router文件夾中找到 indexs.js

注意:如果創建項目是沒有安裝router,不會有router文件夾,該文件夾在src 文件夾的根目錄中

// 1.引入路由以及vue,下面的是固定寫法,照寫就可以
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
 
2.創建路由實例
const router = new Router({
  linkActiveClass: 'app-active', // 路由點擊選中時的顏色(app-active爲自定義的class樣式類)
  routes: [
    { // 根路徑
	path: '/',
	redirect: '/home',
	component: () => import('@/pages/home')  // 路由懶加載寫法
    },
    {
	path: '/home',
	name: 'home',
	component: () => import('@/pages/home'),
    }
})
 
/* 路由攔截器 路由跳轉前的操作 */
router.beforeEach((to, from, next) => {
   next()
})
/* 路由攔截器 路由跳轉後的操作 */
router.afterEach(to => {
 
})
 
3.將路由導出,供外部接收,主要用於main.js接收
export default router

2.配置好router中的index.js文件後需要在main.js 中,掛載路由router到vue實例上

import Vue from 'vue'
import App from './App'
import router from './router' // 導入配置好的路由文件
import store from './store'  // 導入配置好的vuex文件
Vue.config.productionTip = false
 
new Vue({
  el: '#app',
  router, // 掛載路由到實例中 
  store,// 掛載vuex到實例中
  components: { App },
  template: '<App/>'
})

  通過上面兩步,路由的基本配置已經完成可以正常使用路由了。
路由元信息meta使用

1.路由攔截器

     router.beforeEach( to, from,  next )

     router.afterEach( to,  from )

參數說明:

     to:表示要跳轉的路由對象。

     from:表示跳轉前的路由對象

     next:繼續執行跳轉的函數,只有跳轉前的攔截纔有這個參數。

import Router from 'vue-router'
Vue.use(Router)
 
const router = new Router({
  routes: [{
    path: '/',
    redirect: '/home',
    component: () => import('@/pages/home') 
  }]
})
 
/* 路由攔截器 路由跳轉前的操作 */
router.beforeEach((to, from, next) => {
    /* 路由跳轉前可進行各種操作,如數據處理,權限驗證,取消上頁所有網絡請求等等,
     *一定要注意,數據處理後,一定要執行next(),否則路由不會進行跳轉。*/
    if(true){
       // 進行的操作
       next()
    }else{
       // 進行的一些操作
      next()
    }
   
})
/* 路由攔截器 路由跳轉後的操作 */
router.afterEach(to => {
    // 在這裏執行路由跳轉成功後所進行的操作
})
 
export default router

上面已經解了攔截器的基本使用,下面再來看一下,攔截器結合路由元信息meta的使用。

2.路由攔截器中元信息meta對象的使用----登陸攔截驗證 和 修改頁面的 title

場景描述如下圖:

1.用戶訪問home頁面,或者home的子頁面mine頁面時,由於home只有登陸後才能進入,所以用戶在訪問這兩個頁面時需要判斷是否登錄,如果沒有登錄就跳轉到登錄頁面,登錄成功後自動跳轉到用戶訪問的權限頁面。

2.當調轉對應的路由頁面時,就更改網頁的名字,也就是index.heml 中 head 標籤裏面的 title 的值

(1)、首先準備三個路由頁面,home.vue 、 login.vue 、mine.vue

/*------------------------------------------home.vue------------------------------------------*/
<template>
   <div>
        <h1>首頁</h1>
        <router-link to="/home/mine">前往首頁子頁面</router-link>
        <router-view></router-view>
    <div>
</template>
   ...
/*------------------------------------------mine.vue------------------------------------------*/
<template>
   <div>
        <h1>子頁面</h1>
    <div>
</template>
   ...
/*------------------------------------------login.vue------------------------------------------*/
<template>
   <div>
        <h1>登錄頁面</h1>button
        <button @click="login">前往首頁子頁面</button>
    <div>
</template>
<script>
   ...
    methodes:{
       login(){ 
          localStorage.login = true // 登錄狀態
            // this.$route.params.redirect 是路由攔截是傳過來的攔截頁面的路由對象,看下文的路由攔截配置詳情,有說明。
          if( this.$route.params.redirect ){   // 判斷是否有redirect參數 
              this.$router.push( this.$route.params.redirect ) 登錄後跳回被的攔截
          }     
       }
    }
...
</script>

(2)、在路由配置router/index.js文件中  設置路由攔截

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
  routes: [
    { // 根路徑
        path: '/',
        redirect: '/home',
        component: () => import('@/pages/home'),  // 路由懶加載寫法
    },{
        path: '/home',
        name: 'home',
        component: () => import('@/pages/home'),
        meta:{ 
            isLogin : true  // 自定義一個屬性,true需要登錄權限
            title:"主頁"
        },
        children:[{
            path: 'mine',
            name: 'mine',
            component: () => import('@/pages/home/mine'),
            meta:{ // 不做登錄權限的設置
                title:"用戶中心頁"
            }  
	}]
    },{
        path: '/login',
        name: 'login',
        component: () => import('@/pages/login'),
        meta:{
            title:"登錄頁"
        }
    },
})
 
  //導航前守衛(跳轉前)
  router.beforeEach(function(to,from,next){
    // to: 表示要跳轉的頁面。from:表示從哪個頁面來
    let login_in = localStorage.login                  // 是否已登錄
    let require = to.matched.some(function(item){      // 是否需要登錄
      return item.meta.isLogin
    })
    if( !login_in && require ){       // 當未登錄,且跳轉的頁面需要登錄後才能操作時,進行路由攔截
      next({                          // 跳轉登錄頁
        name: "login",
        params: { redirect: to }      // 將 要跳轉(即被攔截) 的路由對象,作爲參數,傳遞到登錄頁面
      });
    }else{                            // 已登錄就正常跳轉,不做任何攔截
      next()                          // 正常跳轉到下一頁
    }
  })
  //導航後守衛(跳轉後)
  router.afterEach(function(to,from){
       document.title = to.meta.title     //跳轉後設置頁面的title
  })
export default router

 到此所需的功能我們已經實現了。

      細心的人可能會發現 beforeEach 攔截器中 變量 require  的值不是應該直接用路由meta.isLogin 的值 即 to.meta.isLogin的值?。爲什麼使用了數組some()方法對to.matched進行循環,來賦值?to.matched又指的是什麼?

      這一步很重要,不能直接使用to.meta.isLogin的值,這樣的話只是跳轉到home.vue時會被攔截,但是如果直接在地址欄訪問 home.vue 的子頁面mine.vue時如:localhost:8080/#/home/mine ,就不會進行攔截。

      因爲mine.vue頁面,配置路由時沒有在meta中設置 isLogin,所以to.meta.isLogin的值是false,會直接跳轉不會進行攔截。所以要循環to.matched 進行判斷。說了這麼多,咱來看一下to.matched指的是什麼:

    to.matched 返回的是一個數組,裏面是存放的是路由對象,指當前匹配的路徑中所包含的路由片段所對應的路由對象。

比如:localhost:8080/#/home/mine 這個路徑中我看到有兩個路由片段home 和 mine

     因此to.matched 的數組存放的就是 home 和 mine 的路由實例。用數組some()循環方法,是匹配數組中所有元素,只要有一個元素的某個值到達了條件 item.meta.isLogin 爲true,該方法就會返回true。所以直接訪問mine頁面時,to.matched數組中,home對象的meta.isLogin是true,達到了條件,所以整體返回了true,此時 require 的值即爲true。 不懂數組some()方法的可以去惡補一下ES6-數組新增的方法。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章