权限hook封装,vue和react封装hook区别
1、本人是个vue、react之间反复横跳的狗砸。
2、公司新开项目,公司前端技术委员会(我和另外一个前端小朋友)(我们公司就两个前端)研究决定,从antd pro转战 vue3 + vite。且暂时不使用一把梭方案。
后面新项目中,关于权限逻辑hook的重新封装,导致对于react、vue有了些相关的思考。
一、权限设计逻辑
-
角色配置权限菜单。
-
用户账号,绑定角色。
-
用户登录,获取用户权限详情。
-
根据权限详情,每个页面根据权限判断按钮等显示、隐藏等。
权限菜单数据结构
[
{
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