iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0

今天繼續研究 pure-admin-thin
主題是 v-auth

第一次看到還以為是類似 v-if v-for 官方的 vue 語法,一查之下才知道它叫做vue directive,是客製化語法,也就是說開發者可以自訂義語法操作元素節點!
更詳細的部分讀者可以參考這篇文章:https://ithelp.ithome.com.tw/articles/10272564


TLTR

  • \pure-admin-thin\src\views\permission\button\index.vue
    • 作者的權限範例 vue 檔案
  • \pure-admin-thin\src\main.ts
    • 在 main 全域引用 vue directive 之後都能直接使用不用另外引入
  • \pure-admin-thin\src\directives\permission\index.ts
    • permission directives
  • \pure-admin-thin\src\store\modules\permission.ts
    • permission store
    • 額外把權限抽出來放在共用儲存區,讓上面index.ts變得很好閱讀

權限範例檔案

//\pure-admin-thin\src\views\permission\button\index.vue
<script setup lang="ts">
import { ref } from "vue";
// 引入 TypeScript 定義的設定檔
import type { StorageConfigs } from "/#/index";
// 引入作者封裝的 session 物件,用法和 localStorage 類似
import { storageSession } from "@pureadmin/utils";

// \pure-admin-thin\mock\asyncRoutes.ts 定義的路由 components name
// 如果名稱不同 router 會抓不到,無法渲染該 vue 檔案
defineOptions({
  name: "PermissionButton"
});

// 定義變數 auth 存目前的角色,預設先去抓 session,若抓不到 = "admin"
const auth = ref(
  storageSession.getItem<StorageConfigs>("info").username || "admin"
);

// 更改角色方法
function changRole(value) {
  console.log(value);
  storageSession.setItem("info", {
    username: value,
    accessToken: `eyJhbGciOiJIUzUxMiJ9.${value}`
  });
  // 先註解後觀察 session 的 info 值是甚麼
  // window.location.reload();
}
</script>

<template>
  <el-card>
    <template #header>
      <div class="card-header">
        <!-- v-model 綁定 key -->
        <el-radio-group v-model="auth" @change="changRole">
          <!-- label 即是 value -->
          <!-- 會傳給 changRole(value) -->
          <el-radio-button label="admin" />
          <el-radio-button label="test" />
        </el-radio-group>
      </div>
    </template>
    <!-- 已經全域引用 vue directive 所以可以直接用自訂義語法 v-auth-->
    <!-- 只有符合特定的角色時才會渲染,否則移除該 DOM 節點 -->
    <p v-auth="'v-admin'">只有admin可看</p>
    <p v-auth="'v-test'">只有test可看</p>
  </el-card>
</template>

main.ts 引用 directives

//\pure-admin-thin\src\main.ts
// 第31行
// 自定義指令
import * as directives from "/@/directives";
Object.keys(directives).forEach(key => {
  app.directive(key, (directives as { [key: string]: Directive })[key]);
});

權限(permission)的指令(directive)

//\pure-admin-thin\src\directives\permission\index.ts
// 引入抽出去共用區的 permission hook
import { usePermissionStoreHook } from "/@/store/modules/permission";
// 引入 vue 規定的 Directive
import { Directive } from "vue";
import type { DirectiveBinding } from "vue";

export const auth: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
  //如果是 v-auth="'v-admin'" , value = 'v-admin'
    const { value } = binding;
    if (value) {
      const authRoles = value;
      //這邊做了很多事情,作者把它抽出去
      //會判斷權限共用區的buttonAuth有沒有包含'v-admin'沒有下面做移除
      const hasAuth = usePermissionStoreHook().buttonAuth.includes(authRoles);
      if (!hasAuth) {
          //原生語法 移除元素節點
        el.parentNode.removeChild(el);
      }
    } else {
      throw new Error("need roles! Like v-auth=\"['admin','test']\"");
    }
  }
};

permission共用儲存區的檔案路徑:
\pure-admin-thin\src\store\modules\permission.ts

因為程式碼比較多只擷取這段重點

//...略 第22行開始
  actions: {
    /** 路由菜單 */
    asyncActionRoutes(routes) {
//...略

    //爬取 \pure-admin-thin\mock\asyncRoutes.ts 定義的路由
    //裡面如果有 authority 就在 buttonAuth 陣列新增資料
      const getButtonAuth = (arrRoutes: Array<RouteConfigs>) => {
        if (!arrRoutes || !arrRoutes.length) return;
        arrRoutes.forEach((v: RouteConfigs) => {
          if (v.meta && v.meta.authority) {
            this.buttonAuth.push(...v.meta.authority);
          }
          if (v.children) {
            getButtonAuth(v.children);
          }
        });
      };
      getButtonAuth(this.wholeMenus);
      
//...略      

看完上面這段就大致能理解上面出現的buttonAuth.includes(authRoles)意義是甚麼了


參考文章

[Vue3.x]: script setup语法糖通过defineOptions定义组件name
https://juejin.cn/post/7075908280383455268

複習 vue-pure-admin 全域設定檔
https://ithelp.ithome.com.tw/articles/10294235

pure-admin-utils 文件
https://pure-admin-utils-docs.vercel.app/guide/guide.html
找不到原始碼,只知道打包後的 code


上一篇
第十二天 pure-admin 部署設定
下一篇
第十四天 vure-admin 用了哪些 icon 圖庫?
系列文
教練我想做一個後台管理系統,阿我忘記我只有一個人沒有教練,那用試著以vue-pure-admin為基底做做看31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言