likes
comments
collection
share

权限hook封装,vue和react封装hook区别

作者站长头像
站长
· 阅读数 46

1、本人是个vue、react之间反复横跳的狗砸。

2、公司新开项目,公司前端技术委员会(我和另外一个前端小朋友)(我们公司就两个前端)研究决定,从antd pro转战 vue3 + vite。且暂时不使用一把梭方案。

后面新项目中,关于权限逻辑hook的重新封装,导致对于react、vue有了些相关的思考。

一、权限设计逻辑

  1. 角色配置权限菜单。

  2. 用户账号,绑定角色。

  3. 用户登录,获取用户权限详情。

  4. 根据权限详情,每个页面根据权限判断按钮等显示、隐藏等。

权限hook封装,vue和react封装hook区别

权限菜单数据结构

[
{
    id: 15,
    name: '角色管理',
    type: 'page',
    key: '/system/role',
},{    id: 16,
    name: '角色获取',
    type: 'opration',
    key: '/system/role/get',
},]

**key:路由 + 操作name值;**每个页面根据 路由 + 操作name去匹配 用户详情获取到的 权限数组,就可以判断该操作有没有权限。

二、hook (react)

react是函数式组件。状态刷新,会触发整个函数式组件的渲染执行。usecallback 可以根据最新的状态返回一个最新的函数。 直接使用就好了。

备注:由于本人换电脑了,下面的所有代码,只提供封装思路。react代码,偷懒。没有些ts相关。整体代码量其实和 vue 差不多。

①、hook代码

import { useCallback } from 'react';
import { history } from 'umi';

export default () => {
  const { location  } = history;
  const { pathname } = location;
  const jFun = useCallback((jKeyInit: string) => {
    const { permissionIdList, isSuper } = commonStore || {};
    const fullPath = jKeyInit.includes('/') ? jKeyInit: `${pathname}/${jKeyInit}`;
    return isSuper || permissionIdList.includes(fullPath);;
  }, [commonStore]);

  return {
    jFun,
  }
}

②、使用

import styles from './index.less';
import useHook from './hooks';

export default function IndexPage() {
  const { jFun } = useHook();
  return (
    <div>
      {
        jFun('add') && <h1 className={styles.title}>新增</h1>
      }
    </div>
  );
}

三、hook (vue)

template内,会受ref状态数据影响,进行动态刷新渲染。可以直接使用jFun进行判断渲染。

script标签内,默认只执行 setup的那次。后续异步获取完数据,并不会触发。

所以这里需要写个watch 再挂一个钩子出去,触发权限相关动作。

以下是一个例子。在有get权限后,触发,列表数据请求。

①、hook代码

import { ref, watchEffect , toRaw } from 'vue';
import { useCommomStore } from '@/models';
import { useRouter } from "vue-router";

type jKeyType = 'add'| 'edit'| 'delete'| 'get';
interface MyProps {
  jKey?: jKeyType | string;
  created?: (jFun: (jkey: string) => boolean) => void;
}
let isFirst: any = undefined;
export default (props: MyProps) => {
  const {
    jKey = '',
    created = () => {},
  } = props || {};
  const { currentRoute }: any = useRouter();
  const { path } = currentRoute.value || {};
  const commonStore = useCommomStore();
  const jOk = ref<boolean>(false);
  const jFunBase = ref<any>();

  watchEffect(() => {
    const { permissionIdList, isSuper } = commonStore;
      if ((isSuper || permissionIdList!== undefined) && !isFirst) {
        isFirst = true;

        const jFun = (jKeyInit: string) => {
          const fullPath = jKeyInit.includes('/') ? jKeyInit: `${path}/${jKeyInit}`;
          return isSuper || toRaw(permissionIdList).includes(fullPath);
        }
        jFunBase.value = jFun;
        created(jFun);
        if (jKey) {
          jOk.value = jFun(jKey);
        } 
      } 
  });

  return {
    jOk,
    jFun: jFunBase.value || (() => false),
    permissionIdList: commonStore.permissionIdList,
    isSuper: commonStore.isSuper,
  }
}

②、使用

import { useJuir } from '@/hooks';

const { jFun } = useJuir({
  canChecked: (jFunBase) => {
    if (jFunBase('get')) {
      getTable();
    }
  }
});

<template>
    <a-button type="primary" @click="modalVisible = true" v-if="jFun('add')">新增</a-button>
</template>

四、hook封装的区别及思路

①、hooks 封装核心思路

抽离能复用的状态。或者和状态相关的操作。

②、react、vue关于hook封装区别

react内,状态只要有变化,就会触发整个对应函数式组件的刷新渲染。

而vue内,状态的变化,会自动触发**template**内的刷新动作。但不会触发**script**标签内的执行。这个时候,需要 watch去手动监听执行。

vue可以把 watch写在hook内,挂载一个钩子出去。

五、总结

关于这儿两种写法hook封装,我更喜欢 react的,简单粗暴。

等段时间写一期,react、vue, hooks 相关生态整理?

转载自:https://juejin.cn/post/7088621970949931044
评论
请登录