vue.js除了動態路由,前端許可權還可以這麼玩

ccfish發表於2018-03-22

索引

概述

關於動態路由的相關處理,請參考本人的另一篇文章vue.js前後端分離後臺,該如何根據使用者許可權處理前端顯示和後臺介面訪問,本文作為上一篇的續作
有時候僅處理選單,是不夠的,很多情況下,有讀的許可權,但無寫的許可權的時候,就需要更靈活的控制。也就是這篇文章的由來。

大概有兩種方式可以使用:

  1. 指令
  2. 元件

基於指令

關於指令的使用,網上的文章比較多了,主要是操作DOM,把沒有許可權的元素從已渲染的畫面裡面刪除。這裡只是簡單的出個示範,具體可以參考自己的授權系統開發:

import Vue from `vue`
// import Store from `../store/`

const directives = {
  role: {
    // 指令的定義 (TBD:有沒有before`inserted`這樣的鉤子函式用?)
    inserted: (el, binding, vnode) => {
      // 許可權
      if (binding.value && [處理許可權的判定]) {
        el.parentElement.removeChild(el)
      }
    }
  }
}

Object.keys(directives).forEach(key => {
  Vue.directive(key, directives[key])
})
<el-button type="success" icon="el-icon-document" size="small" v-role="xxx-upload"
                   @click="$router.push({name: `music-album-multi-upload`})">上傳
        </el-button>

基於元件

不確定對於vue元件,有沒有全域性的生命週期鉤子,如果有的話,處理起來就更方便了。
下面就以普通的元件形式來說明下處理過程:

寫一個全域性的元件,註冊為v-sec,其中引數code為訪問當前畫面segment的授權碼。

<template>
  <div>
    <slot v-if="permitted"></slot>
  </div>
</template>

<script>
  import vuet from `@/vuet/`

  export default {
    name: "sec",
    props: {
      code: {
        type: String,
        required: true,
        default: `text`
      },
    },
    data() {
      return {
        permitted: false
      }
    },
    beforeCreate() {
      let userSelf = vuet.getModule(`user-self`)
      if (userSelf /* && userSelf.secCodes && userSelf.secCodes.contains(this.code) */) {
        this.$nextTick(function () {
          this.permitted = true
        })
      }
    }
  }
</script>

然後在畫面上使用

<v-sec code="xxx-add">
  <el-button type="success" icon="el-icon-document" size="small"
             @click="$router.push(`/sys/module/add`)">新增
  </el-button>
</v-sec>

與指令的那種方式在使用方面差不多,如果元件的這種方式能避免內嵌的元件被渲染,那效果會比指令的那種好一些。

接下來,在專案只可能就兩種方式分別做實驗。

許可權的定義

畫面

一般通過導航+動態路由能控制住的,像畫面和選單。
然後配合路由的全域性函式router.beforeEach基本上比較好實現。
為了配合動態路由,需要指定以下幾個欄位

  • 路徑,用於畫面跳轉,
  • 元件名/檔案地址,用於路由生成,指向實際的vue檔案(我們可以約定-代替路徑分隔符:common-main=/src/pages/common/main.vue)
  • 畫面名,用於顯示,導航或Title等地方需要
  • icon,有一些樣式庫裡有這個,作為可選項
  • show_nav,是否顯示在導航中,有一些畫面需要引數的話,不能夠直接從導航進入,可區分開

頁面片段

基本上標記個名字,與畫面關聯起來以便於管理就可以了。
然後配置後臺管理系統,可以通過先通過後臺錄入畫面及畫面片段,然後用程式生成對應的vue檔案及部分程式碼。這樣子開發效率是不是高一些?

  • 畫面ID
  • 片段編碼,不直接使用DB的ID自增,以避免在不同的系統間資料遷移時的問題。
  • 片段名,在授權畫面展示以方便管理

授權

授權時,把畫面和畫面片段與角色關聯即可,然後使用者在登入後獲取到角色,再從記憶體/DB/快取中把角色對應的畫面和選單等許可權查出,合併到一起返回給vue。vue拿到資料後,快取到localstorage以避免畫面的重新整理(f5/瀏覽器重新整理)後出現404的問題,這一點在上一篇裡面已經說明過了。

相關文章