1. 程式人生 > >基於Vue的addRoutes實現許可權控制

基於Vue的addRoutes實現許可權控制

前言

從今年3月到現在入門前端也已經有兩個月了,這兩個月在自學的過程中遇到了許多問題也解決了其中一部分,但是現在才開始意識到把學習過程的問題整理到CSDN上。最近老師佈置了基於Vue的許可權控制,網上查閱了許多部落格,例如“前端路上":這篇文章提到了Vue2.0以上使用的addRoutes增加動態路由的思路。然而我只是一個小白,儘管文章裡貼出了原始碼,我也只能看的一知半解,所以根據文章中提供的思路自己寫了一個小測試demo。

目錄結構

準備工作

在路由配置檔案裡寫上兩個路由表,一個靜態路由表(所有許可權使用者均能訪問如“登入”、“404頁”)和一個動態路由表,預設匯出靜態路由。

const router = new Router({ //靜態路由,登入、404
  mode:'history',
  routes: [
    {
      path: '/login', //登入頁
      name: 'login',
      component: (resolve) => require(['../components/login.vue'], resolve)
    },
    {
      path: '/404',  //404頁
      name: 'err',
      component: (resolve) => require(['../components/err.vue'], resolve)
    },
  ]
});
export default router //預設靜態路由
export const dynamicRouter =[ //動態路由
  {
    path: '/',
    name: 'home',
    meta: {  //新增meta標籤,裡面自定義了roles,用來設定許可權
      roles:['admin','user']  //該路由僅admin和user許可權訪問
    },
    component: (resolve) => require(['../components/home.vue'], resolve)
  },
  {
    path: '/',
    name: 'home2',
    meta: {
      roles:['tourist'] //該路由僅tourist許可權訪問
    },
    component: (resolve) => require(['../components/home2.vue'], resolve)
  },
  {
    path: '/home21',
    name: 'home21',
    meta: {
      roles:['user']
    },
    component: (resolve) => require(['../components/home21.vue'], resolve)
  },
  {
    path: '/home11',
    name: 'home11',
    meta: {
      roles:['admin']
    },
    component: (resolve) => require(['../components/home11.vue'], resolve)
  },
];

這裡我們已經配置好了路由表。

思路

如果使用者沒有登入,那就將頁面重定向到“/login”,實現方法:在跟元件(App.vue)的created回撥裡做判斷

methods:{
    judgelogin(){ //methods寫一個判斷是否登入的方法
      let isLogin = store.state.token; //這裡我們從Vuex裡取出token,因為登入請求成功後我們會將後臺返回的token儲存在vuex裡方便使用
      if(!isLogin){ //如果沒有token,那就代表使用者沒有登入
        return this.$router.push('/login'); //重定向到login頁
      } 
    }
  },
created() {
     this.judgelogin(); //在created裡呼叫上面構造的方法
  }

登入頁:

HTML:
template>
  <div id="login">
    <form>
      <label>賬號</label><input type="text" v-model="username"/><br>
      <label>密碼</label><input type="password" v-model="password"/><br>
      <input type="button" value="登入" @click="Login">
    </form>
  </div>
</template>
JS:
import {router,dynamicRouter} from '../router/index' //獲取路由配置檔案裡的兩個路由表

export default {
  name: 'login',
  data () {
    return {
      username:'', //雙向繫結獲取賬號
      password:'', //雙向繫結獲取密碼
    }
  },
  methods:{
    Login(){
      sessionStorage.setItem('token',this.username); //將token和roles儲存下來,因為沒有後臺介面,我這邊就將賬號當做token和roles
      sessionStorage.setItem('roles',this.username);
      let dR = new Array(); //建立一個數組用來儲存符合許可權的路由
      for (let i=0;i<dynamicRouter.length;i++){ //第一層迴圈遍歷動態路由表的每一個路由
        for (let j=0;j<dynamicRouter[i].meta.roles.length;j++){ //第二次迴圈遍歷每一個路由裡的roles設定的許可權並和當前登入賬號的許可權比較
          if (dynamicRouter[i].meta.roles[j] == this.username){ //這裡因為我預設賬號名就是當前使用者的許可權
           dR.push(dynamicRouter[i]); //符合條件的路由資訊就放進數組裡
         }
        }
      }
      this.$router.addRoutes(dR.concat([{ //這裡呼叫addRoutes方法,動態新增符合條件的路由
        path: '*',
        redirect: '/404' //所有不匹配路徑(*)都重定向到404,為什麼寫在這裡而不放到靜態路由表裡可以檢視“前端路上”的文章
      }]));
      this.$router.push('/'); //登入驗證後跳轉到主頁"/"
    }
  },
  created(){
    sessionStorage.clear(); 
  }
}

到這裡我們用賬號“admin”登入後就可以成功跳轉到主頁並顯示"home.vue"的內容,我們也可以修改url訪問"/home11"。但是當我們訪問"/home2"和"/home21"的時候沒有出現我們預期的跳轉到"/404"頁,這裡出了一個bug不知道為什麼,希望用大神能夠指正出來,小弟感激不盡!

前方有坑:

登陸後,當我們按"F5"鍵重新整理頁面後,頁面內容都消失不見了(理論上應該是/404頁內容)。原來addRoutes和Vuex一樣都是重新整理後資料會清空(這個地方我感覺是真的坑)。這是因為重新整理會導致Vue重新例項化,路由也恢復到了初始路由,也就是前面的靜態路由表。

改進:

在根元件的created回撥裡,我們不僅得判斷使用者是未登入狀態還是登陸後又重新整理,改進程式碼如下

judgeLogin(){
      let isLogin = store.state.token;
      if(!isLogin){
        return this.$router.push('/login');
      } else {
        let dR = new Array();
        for (let i=0;i<dynamicRouter.length;i++){
          for (let j=0;j<dynamicRouter[i].meta.roles.length;j++){
            if (dynamicRouter[i].meta.roles[j] == store.state.roles){
              dR.push(dynamicRouter[i]);
            }
          }
        }
        this.$router.addRoutes(dR);
      }
    }

這樣即使重新整理,你生成的動態路由也不會失效了。

附上:

因為是小測試,所以Vuex裡只存了兩個資料:

export default new Vuex.Store({
  state:{
    token:sessionStorage.getItem('token'), 
    roles:sessionStorage.getItem('roles'),
  },
})

結:

第一次寫部落格還是有點激動的,不知道這個許可權控制思路能不能對大家有所幫助。這樣的許可權控制其實分不同許可權寫了幾套頁面,然後根據許可權動態新增符合許可權的頁面。其實我一開始的設想是一個主頁的選單欄根據不同許可權的使用者顯示不同的導航(這個實現效果看“前端路上”大能分享的github上原始碼),但是技術有限還未能實現,後續實現後會貼出來的。