电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

react-router v6實現(xiàn)權(quán)限管理+自動替換頁面標題的案例

瀏覽:239日期:2022-06-09 16:11:51
目錄
  • 權(quán)限管理
  • 總結(jié)

學(xué)了一段時間的react+ts,想著寫一個項目練練手,由于初次寫react+ts項目,有很多東西并不知道應(yīng)該怎么寫,再加上之前寫vue項目的習(xí)慣,突然轉(zhuǎn)換react有點不習(xí)慣,有很多在vue中的寫法,并不知道是否在react中仍然可行。寫項目之前先考慮了權(quán)限管理,第一次使用react-router v6 也不知道是否有更好的寫法。這次就來簡單分享一下我實現(xiàn)權(quán)限管理以及攔截器中遇到的一些問題。

權(quán)限管理

這次項目是有三種權(quán)限,分別是用戶,商家以及管理員。這次寫的權(quán)限管理是高級權(quán)限能訪問低級權(quán)限的所有頁面,但是低級權(quán)限不能訪問高級權(quán)限的頁面。
簡單實現(xiàn)

// 在這里進行判斷用戶權(quán)限使用不同的頁面
import React from "react";
import Merchant from "../pages/merchant";
import Admin from "../pages/admin";
import User from "../pages/user";
export default function Index() {
//這里使用power來判斷是否登錄,以及權(quán)限
  let power = localStorage.getItem("power");
  return (
    <div>
      {power ? (
power === "1" ? (
  <Merchant></Merchant>
) : (
  <Admin></Admin>
)
      ) : (
<User></User>
      )}
    </div>
  );
}

我實現(xiàn)權(quán)限管理的方式就是根據(jù)不同的權(quán)限掛載不同的頁面,在頁面中實現(xiàn)掛載不同的路由。
之后看一下我在三種不同頁面中的路由定義以及具體內(nèi)容,即不需要顯示的路由就不應(yīng)該被注冊
user路由表

// 引入路由
import Login from "../pages/user/login";
import Register from "../pages/user/register";
import NoPower from "../pages/error/noPower";
import NoPage from "../pages/error/noPage";
import { myRouteObj } from "../type";
//這里的myRouteObj是我自定義的一個類型用于拓展title實現(xiàn)頁面標題的自動切換
export const userRoutes: myRouteObj[] = [
  {
    path: "/404",
    element: <NoPage></NoPage>,
    title: "404"
  },
  {
    path: "/login",
    element: <Login></Login>,
    title: "登錄"
  },
  {
    path: "/register",
    element: <Register></Register>,
    title: "注冊"
  },
];
const routes = [
  ...userRoutes,
  {
    path: "*",
    element: <NoPower></NoPower>,
    title: "沒有權(quán)限"
  },
];
export default routes;

路由表中暴露了兩個對象,分別是最"原始的對象"和使用的對象,這兩個對象的區(qū)別就是是否有攔截器,為什么需要把這個給區(qū)分開,是因為我們的目的是高權(quán)限的用戶能訪問到低權(quán)限用戶所能訪問的頁面,又由于我們是通過返回不同的頁面來實現(xiàn)的權(quán)限管理(即使用過程中必須高權(quán)限的路由中包含低權(quán)限的路由)而且攔截器必須要放在最后,所以就分了兩個來暴露,一個是供注冊路由使用(有攔截器版本),另一個是由高級權(quán)限路由表合并使用

myRouteObj的內(nèi)容

import { NonIndexRouteObject } from "react-router";
export interface myRouteObj extends NonIndexRouteObject {
  title?: string;
}

user頁面的入口文件

import React from "react";
import userRoutes from "../../router/user";
import { useMyRoutes } from "../../hooks/route";
export default function User() {
//這里的useMyRoutes是我自己封裝的一個鉤子函數(shù)
  const element = useMyRoutes(userRoutes);
  return <div>{element}</div>;
}

useMyRoutes鉤子函數(shù)的具體內(nèi)容
該鉤子函數(shù)用于更換頁面標題以及一級路由表中是否有該路由(沒有的話會跳到404),這里為什么只判斷了一級路由表是因為我個人感覺一級路由如果輸入錯誤,其就應(yīng)該跳轉(zhuǎn)到404頁面,而二級路由輸入錯誤,應(yīng)該重定向到二級路由正確的位置,這樣我感覺對用戶要更友好一點,所以我在二級路由中添加了重定向的功能,并且也實現(xiàn)了替換標題的功能,如果沒有標題的話會返回一個默認值

import { useEffect } from "react";
import { useLocation, useNavigate, useRoutes } from "react-router";
import { myRouteObj } from "../type";
function flatDeep(children: any, findArr: any): string {
  // 判斷children數(shù)組中是否有想要的元素
  let tempArr = children.map((item: any) => item.path);
  let index = tempArr.indexOf(findArr[0]);
  if (index !== -1) {
    return findArr.length > 1
      ? flatDeep(children[index], findArr.splice(1, findArr.length))
      : children[index].title;
     ? children[index].title
     : "商城";
  }
  return "商城";
}
export function useMyRoutes(routes: myRouteObj[]) {
  // 判斷路由表中是否有對應(yīng)路由,如果沒有就返回到404
  const location = useLocation();
  const navigate = useNavigate();
  useEffect(() => {
  /*
這里有一個小問題,困擾了我半天,就是原本我獲取路徑是寫在useEffect外邊的,頁面每次刷新就會顯示成錯誤的標題,最后輸出是因為報存的值沒有更新,所以就改到useEffect函數(shù)里邊了
*/
    // 非空
    const firstPathName = location.pathname
      .split("/")
      .filter((item) => item !== "");
    const firstPath = routes.map((item) => item.path?.split("/")[1]);
    let index = firstPath.indexOf(firstPathName[0]);
    if (!index) {
      navigate("/404");
      return;
    }
    // 判斷是否是首頁
    if (location.pathname === "/") {
      document.title = "商城";
      return;
    }
    // 判斷是幾級路由
    if (firstPathName.length > 1) {
      // 多級
      document.title = flatDeep(
routes[index].children,
firstPathName.splice(1, firstPathName.length)
      );
      return;
    }
    // 一級
    document.title = routes[index].title
      ? (routes[index].title as string)
      : "商城";
  }, [location, navigate, routes]);
  return useRoutes(routes);
}

商家的路由表

import { Navigate } from "react-router";
import Merchant from "../pages/merchant";
import Commodity from "../pages/merchant/commodity";
import { userRoutes } from "./user";
import { getRoutesObj } from "../utils";
import { myRouteObj } from "../type";
const children: myRouteObj[] = [
  {
    path: "commodity",
    element: <Commodity></Commodity>,
  },
];
const primitiveObj = {
  path: "/merchant/*",
  element: <Merchant></Merchant>,
  title: "商店后臺"
};
// 有攔截器版本
export const [routes, defaultRoutes] = getRoutesObj(
  userRoutes,
  primitiveObj,
  children,
  {
    path: "*",
    element: <Navigate to="/merchant/commodity"></Navigate>,
  }
);

getRoutesObj是我自定義的為二級路由添加重定向的工具函數(shù),至于為什么封裝這個函數(shù),其原因就是商家和管理員都要使用,原本是想把重定向添加到最外層,但是這個由于react-router v6并不是嚴格匹配模式,所以即使匹配上路由也會嘗試往下匹配更精確的路由比如/about和/about:id所以封裝了該函數(shù)添加二級攔截器

import { myRouteObj } from "../type";
// 第一個參數(shù)是復(fù)用的數(shù)組對象,第二個參數(shù)是有攔截器的對象
/**
 *生成路由表配置(加攔截器)
 * @export
 * @param {myRouteObj[]} reuseObj 復(fù)用的數(shù)組對象
 * @param {myRouteObj} targetObj 目標對象
 * @param {myRouteObj[]} childrenObj 子級路由
 * @param {myRouteObj} globalinterceptorObj 全局攔截路由
 * @param {myRouteObj} interceptor 可選攔截器對象(添加子級路由中)
 */
export function getRoutesObj(
  reuseObj: myRouteObj[],
  targetObj: myRouteObj,
  childrenObj: myRouteObj[],
  interceptorObj?: myRouteObj
) {
  //  先復(fù)制一份children
  const children = [...childrenObj];
  //   判斷是否有值
  if (interceptorObj) {
    children.push(interceptorObj);
  }
  return [
    [
      ...reuseObj,
      {
...targetObj,
children: children,
      },
    ],
    [
      ...reuseObj,
      {
...targetObj,
children: [...childrenObj],
      },
    ],
  ];
}

商家入口文件

import React, { Fragment } from "react";
import { Outlet } from "react-router";
import { routes } from "../../router/merchant";
import { useMyRoutes } from "../../hooks/route";
import { myRouteObj } from "../../type";
export default function Merchant() {
  const element = useMyRoutes(routes as myRouteObj[]);
  return (
    <Fragment>
      {element}
      <Outlet></Outlet>
    </Fragment>
  );
}

管理員的和商家的差不多,這里就不再過多敘述了

總結(jié)

實現(xiàn)這個權(quán)限管理還是花了有一天多的時間,有很多東西沒有這么寫過,也不知道正規(guī)的是否應(yīng)該這樣寫,不過現(xiàn)在還是先實現(xiàn)功能就行了,等之后隨著不斷的練習(xí)和學(xué)習(xí),也能檢驗我這個方法是否是對的,第一次寫react+TS的項目,仍有很多不足,如果哪位大佬有覺得不妥的地方,也歡迎指出,一同學(xué)習(xí),共同進步。

到此這篇關(guān)于react-router v6實現(xiàn)權(quán)限管理+自動替換頁面標題的文章就介紹到這了,更多相關(guān)react-router v6權(quán)限內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

標簽: JavaScript
主站蜘蛛池模板: 钢制暖气片散热器_天津钢制暖气片_卡麦罗散热器厂家 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 防水套管厂家-柔性防水套管-不锈钢|刚性防水套管-天翔管道 | 潜水搅拌机-双曲面搅拌机-潜水推进器|奥伯尔环保 | 天一线缆邯郸有限公司_煤矿用电缆厂家_矿用光缆厂家_矿用控制电缆_矿用通信电缆-天一线缆邯郸有限公司 | 钢托盘,钢制托盘,立库钢托盘,金属托盘制造商_南京飞天金属制品实业有限公司 | 睿婕轻钢别墅_钢结构别墅_厂家设计施工报价 | 仿真茅草_人造茅草瓦价格_仿真茅草厂家_仿真茅草供应-深圳市科佰工贸有限公司 | 纸张环压仪-纸张平滑度仪-杭州纸邦自动化技术有限公司 | 泡沫消防车_水罐消防车_湖北江南专用特种汽车有限公司 | 萃取箱-萃取槽-PVC萃取箱厂家-混合澄清槽- 杭州南方化工设备 | 定制异形重型钢格栅板/钢格板_定做踏步板/排水沟盖板_钢格栅板批发厂家-河北圣墨金属制品有限公司 | 基业箱_环网柜_配电柜厂家_开关柜厂家_开关断路器-东莞基业电气设备有限公司 | 二手电脑回收_二手打印机回收_二手复印机回_硒鼓墨盒回收-广州益美二手电脑回收公司 | 大米加工设备|大米加工机械|碾米成套设备|大米加工成套设备-河南成立粮油机械有限公司 | 搜活动房网—活动房_集装箱活动房_集成房屋_活动房屋 | 磁力加热搅拌器-多工位|大功率|数显恒温磁力搅拌器-司乐仪器官网 | 自动配料系统_称重配料控制系统厂家 | 杭州代理记账费用-公司注销需要多久-公司变更监事_杭州福道财务管理咨询有限公司 | 云南成考网_云南成人高考报名网 粤丰硕水性环氧地坪漆-防静电自流平厂家-环保地坪涂料代理 | LED灯杆屏_LED广告机_户外LED广告机_智慧灯杆_智慧路灯-太龙智显科技(深圳)有限公司 | 深圳市简易检测技术有限公司| 展厅设计公司,展厅公司,展厅设计,展厅施工,展厅装修,企业展厅,展馆设计公司-深圳广州展厅设计公司 | 次氯酸钠厂家,涉水级次氯酸钠,三氯化铁生产厂家-淄博吉灿化工 | 减速机_上海宜嘉减速机| 包装机_厂家_价格-山东包装机有限公司 | 深圳宣传片制作-企业宣传视频制作-产品视频拍摄-产品动画制作-短视频拍摄制作公司 | 光伏家 - 太阳能光伏发电_分布式光伏发电_太阳能光伏网 | 无线讲解器-导游讲解器-自助讲解器-分区讲解系统 品牌生产厂家[鹰米讲解-合肥市徽马信息科技有限公司] | 自恢复保险丝_贴片保险丝_力特保险丝_Littelfuse_可恢复保险丝供应商-秦晋电子 | 番茄畅听邀请码怎么输入 - Dianw8.com | 货车视频监控,油管家,货车油管家-淄博世纪锐行电子科技 | 北京中创汇安科贸有限公司 | 托利多电子平台秤-高精度接线盒-托利多高精度电子秤|百科 | LINK FASHION 童装·青少年装展 河南卓美创业科技有限公司-河南卓美防雷公司-防雷接地-防雷工程-重庆避雷针-避雷器-防雷检测-避雷带-避雷针-避雷塔、机房防雷、古建筑防雷等-山西防雷公司 | 高中学习网-高考生信息学习必备平台 | Safety light curtain|Belt Sway Switches|Pull Rope Switch|ultrasonic flaw detector-Shandong Zhuoxin Machinery Co., Ltd | 气体热式流量计-定量控制流量计(空气流量计厂家)-湖北南控仪表科技有限公司 | 家乐事净水器官网-净水器厂家「官方」 | 隔爆型防爆端子分线箱_防爆空气开关箱|依客思 | 济南展厅设计施工_数字化展厅策划设计施工公司_山东锐尚文化传播有限公司 |