用React给XXL-JOB开发一个新皮肤(二):目录规划和路由初始化

news2024/11/19 15:18:33

目录

  • 一. 简述
  • 二. 目录规划
  • 三. Vite 配置
    • 3.1. 配置路径别名
    • 3.2. 配置 less
  • 四. 页面
    • 4.1. 入口文件
    • 4.2. 骨架文件
    • 4.3. 普通页面
  • 五. 路由配置
  • 六. 预览启动

一. 简述

上一篇文章我们介绍了项目初始化,此篇文章我们会先介绍下当前项目的目录规划,接着对vite 配置以便我们后续的开发,最后会根据 xxl-job 的页面创建我们项目的页面并配置路由信息。

二. 目录规划

一般来说前端项目可以分为下面几个部分:页面、路由、状态管理、静态资源、工具方法。结合我们的项目我调整了下项目的目录结构如下:

  • api:存放 api 定义
  • assets:存放静态文件
  • components:公共组件
  • hooks:公共的 React Hooks
  • pages:存放页面
  • router:路由信息
  • store:存放状态管理文件
  • types:定义的接口交互的接口
  • utils:常用的一些工具类
    在这里插入图片描述

如果有其他的目录结构设计,可以评论区交流!

三. Vite 配置

上面我们规划了项目的目录结构,接着我们配置下 vite

3.1. 配置路径别名

配置路径别名之后可以省去写冗长的相对路径。
在这里插入图片描述
我们只需要在vite.config.ts 中添加如下配置:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from "path";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"),
      "@assets": path.resolve(__dirname, "src/assets"),
      "@pages": path.resolve(__dirname, "src/pages"),
      "@store ": path.resolve(__dirname, "src/store"),
      "@images ": path.resolve(__dirname, "src/assets/images"),
    },
  }
})

另外还需要修改 tsconfig.json,否者引入路径会飘红。

{
  "compilerOptions": {
    
    ...
    
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  ...
}

3.2. 配置 less

我们在项目中使用less 做样式管理,需要在vite.config.ts中配置如下:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from "path";

// https://vitejs.dev/config/
export default defineConfig({
  
  ... 忽略
  
  css: {
    preprocessorOptions: {
      less: {
        // 全局变量
        modifyVars: {},
        javascriptEnabled: true,
      },
    },
  },
})

后续我们在实现切换主题的功能的时候还会在配置这个地方,现在先放一放。

四. 页面

xxl-job 的任务调度中心有登录页面和管理页面组成,而管理页面也是我们常规管理系统的页面结构(结构如下)。
在这里插入图片描述
所以菜单栏、头部、尾部相当于管理页面的骨架,内容部分是需要切换路由动态展示的。做过管理系统的同学们应该很快就可以大体规划出页面模块。下面看一下我在pages 目录下定义的页面模块如下:

  • course:使用教程
  • dispatch:调度日志
  • exception:异常页面
  • executor:执行器管理
  • layout:页面骨架
  • login:登录页面
  • task:任务管理
  • user:用户管理
  • index.tsx:入口文件

日常开发建议:在定义模块目录的时候,最好见名知意,路由表也最好和模块名称对应(遇到 BUG可以最快的定位到问题页面)。主打一个不防御编程。

4.1. 入口文件

在 index.tsx 中,我们会配置引入定义的路由和 antd 的配置组件,内容如下:

import {ConfigProvider} from "antd";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import RouterSpace from "@/router";
import zhCN from "antd/lib/locale/zh_CN";
import routers = RouterSpace.routers;

const Application = () => {
  return <ConfigProvider locale={zhCN}>
    <RouterProvider router={createBrowserRouter(routers)} />
  </ConfigProvider>
}

export default Application;

这里我们使用 ConfigProvider全局化配置:https://ant-design.antgroup.com/components/config-provider-cn,方便我们使用国际化和配置组件样式等,具体可以看文档。

其中<RouterProvider router={createBrowserRouter(routers)} />,是通过createBrowserRouter 创建一个路由表,然后通过RouterProvider向下传递。

这里需要注意下BrowerserRouterHashRouter的区别:

  • BrowerserRouter:利用H5 history API实现url地址改变,并通过 pushStatereplaceState 改变 URL,但不会触发浏览器的刷新。这使得单页应用程序可以像多页应用程序一样具有多个路由;虽然此路由更加自然、美观,但是刷新页面的时候请求服务器,可能会导致 404错误;
  • HashRouter:使用window.location.hash 属性和window.onhashchange事件。可以监听浏览器hash值得变化,去执行相应的Js切换网页。使用 URL 中的 hash#)部分来进行路由管理;正是因为路由信息是存储在 URL 的哈希部分,不会出发服务器请求,但是哈希符号,影响美观;

所以在正常项目中我们都是需要和服务端配置使用的,建议使用BrowerserRouter就可以,在一些涉及到登录认证、菜单权限的权限的时候BrowerserRouter会它的妙用。

4.2. 骨架文件

骨架文件是为了定义公共组件部分,并提取出动态组件部分,代码如下:

import {Link, Outlet} from "react-router-dom"

const LayoutPage = () => {
  return <div>
    {/* 菜单 */}
    <div>
      <Link to={'/xxl-job/report'}>运行报表</Link>
      <br/>
      <Link to={'/xxl-job/task'}>任务管理</Link>
      <br/>
      <Link to={'/xxl-job/dispatch'}>调度日志</Link>
      <br/>
      <Link to={'/xxl-job/executor'}>执行器分管理</Link>
      <br/>
      <Link to={'/xxl-job/user'}>用户管理</Link>
      <br/>
      <Link to={'/xxl-job/course'}>使用教程</Link>
      <br/>
      <Link to={'/login'}>退出登录</Link>
    </div>
    {/* 内容 */}
    <div>
      {/* 头 */}
      <div></div>
      {/* 内容 */}
      <div>
        <Outlet />
      </div>
    </div>
  </div>
}

export default LayoutPage

Outlet 是一个用于渲染子路由的组件。它通常与 Route 配合使用,用于在父路由中指定子路由的渲染位置。Outlet 充当了子路由渲染的占位符,告诉 React Router 在当前组件中的哪里渲染子路由。

LinkReact Router 提供的组件之一,用于在应用中创建导航链接。它通常用于代替传统的 <a> 标签,提供了一种在单页面应用(SPA)中进行客户端路由导航的方式,而无需进行页面的完整刷新。

下一篇文章会介绍 css 组件如何使用。

4.3. 普通页面

除了骨架和入口文件,其他模块暂时都是简单的普通页面,如下图:
在这里插入图片描述
这些模块都如 task 目录下的 index.tsx 文件内容都是类似,内容如下:

const TaskPage = () => {
  return <div>任务管理</div>
}

export default TaskPage;

这里需要注意函数名称的命名规则,在定义导出函数名称的时候,最好是模块 + Page,这样可以很好的区别其他组件和页面组件。

五. 路由配置

我们在入口文件中通过createBrowserRouter(routers)创建路由表,这里面的 routers 就是我们需要定义的路由表结构信息。

import {Navigate, RouteObject} from "react-router-dom";
import LoginPage from "@/pages/login";
import TaskPage from "@/pages/task";
import ReportPage from "@/pages/report";
import DispatchPage from "@/pages/dispatch";
import ExecutorPage from "@/pages/executor";
import UserPage from "@/pages/user";
import CoursePage from "@/pages/course";
import LayoutPage from "@/pages/layout";
import NotFoundPage from "@/pages/exception/404.tsx";

namespace RouterSpace {

  export const routers: RouteObject[] = [
    { path: '/login', element: <LoginPage /> },
    {
      path: '/xxl-job',
      element: <LayoutPage />,
      children: [
        { path: 'report', element: <ReportPage /> },
        { path: 'task', element: <TaskPage /> },
        { path: 'dispatch', element: <DispatchPage /> },
        { path: 'executor', element: <ExecutorPage /> },
        { path: 'user', element: <UserPage /> },
        { path: 'course', element: <CoursePage /> },
        { path: '404', element: <NotFoundPage /> },
        { path: "*", element: <Navigate to={'/xxl-job/404'} /> }
      ]
    },
  ]
}

export default RouterSpace;

后面我们会优化这块路由表,改为 lazy 加载。

这里我们需要注意下RouteObject,现阶段我们只使用了 pathelementchildren 三个属性,这里面还有很多重要的属性可以参看文档:https://reactrouter.com/en/main/route/route#type-declaration。

interface RouteObject {
  path?: string; // 指定路由的路径
  index?: boolean; // 默认子路由ßß
  children?: React.ReactNode; // 定义子路由,是一个包含其他RouteObject的数组。子路由的路径会相对于父路由的路径。
  caseSensitive?: boolean; // 表示路由是否区分大小写,默认为false
  id?: string; // 为路由指定唯一的标识符
  loader?: LoaderFunction; // 一个异步加载函数,用于动态加载路由组件。鉴权的时候使用
  action?: ActionFunction; // 定义路由的生命周期函数,用于在路由渲染前或渲染后执行一些操作
  element?: React.ReactNode | null; // 指定路由匹配时要渲染的 React 元素
  hydrateFallbackElement?: React.ReactNode | null;
  errorElement?: React.ReactNode | null; // 在发生错误时渲染的元素
  Component?: React.ComponentType | null;
  HydrateFallback?: React.ComponentType | null;
  ErrorBoundary?: React.ComponentType | null;
  handle?: RouteObject["handle"];
  shouldRevalidate?: ShouldRevalidateFunction; // 一个函数,用于定义路由是否应该重新验证
  lazy?: LazyRouteFunction<RouteObject>; // 用于懒加载路由的函数
}

其他属性的使用可以参考我的另一个开源项目:https://gitee.com/molonglove/go-react-admin.git,里面有关于动态路由、权限等与路由相关的使用。

这里还有注意点:{ path: "*", element: <Navigate to={'/xxl-job/404'} /> },这个路由定义需要放在最后,意味着如果路由匹配失败会跳转的路由地址。

六. 预览启动

执行 yarn dev查看执行效果,就可以看到如下的效果!
在这里插入图片描述
下一篇文章我们将介绍借助 antd 实现登录页面和管理页面的Layout骨架。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1371273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习JavaEE的日子 day11 初识面相对象

day11 1.初识面相对象 1.1 类和对象的理解 类 * 类是对象的数据类型&#xff0c;类是具有相同属性和行为的一组对象的集合 * 简单理解&#xff1a;类就是对现实事物的一种描述 类的组成 * 属性&#xff1a;指事物的特征&#xff0c;例如&#xff1a;手机事物&#xff08;品牌…

【2023】java常用HTTP客户端对比以及使用(HttpClient/OkHttp/WebClient)

&#x1f4bb;目录 1、介绍2、使用2.1、添加配置2.1.1、依赖2.1.2、工具类2.1.3、实体2.1.4、Controller接口 2.2、Apache HttpClient使用2.3 、OkHttp使用2.4、WebClient使用 1、介绍 现在java使用的http客户端主要包括以下几种 而这些中使用得最频繁的主要是&#xff1a; A…

麒麟系统安装docker、mysql、clickhouse

1、查看麒麟系统版本信息 cat /etc/os-release 麒麟系统版本V10 64位操作系统 # uname -p x86_64 # uname -p aarch64 内核版本 # uname -r 4.19.90-24.4.v2101.ky10.x86_64 本操作为麒麟系统版本V10&#xff0c;x86_64操作系统 一&#xff0c;安装docker 文件&#xff1a…

基于uniapp封装的table组件

数据格式 tableData: [{elcInfo: [{tableData:[1,293021.1,293021.1,293021.1,293021.1,]}]},{elcInfo: [{tableData:[1,293021.1,293021.1,293021.1,293021.1,]}]},{elcInfo: [{tableData:[1,293021.1,293021.1,293021.1,293021.1,]}]},/* {title: "2",elcInfo: [{…

spring-mvc数据绑定和表单标签库(介绍)

spring-mvc数据绑定和表单标签库 1. WEB-INF下页面跳转2. ModelAttribute来注解非请求处理方法3. 表单标签4. 其他标签5. IDEA tomcat控制台中文乱码问题处理 1. WEB-INF下页面跳转 容器启动后&#xff0c;如何默认显示web-inf目录下的系统首页。 2. ModelAttribute来注解非…

mysql生成到当前时间的时间序列,报表按时间补0

生成本月每日的时间序列 SELECT DATE_FORMAT(date_add( CONCAT(YEAR(Date(curdate())),‘-0’,MONTH(Date(curdate())),‘-’,‘01’), INTERVAL ( cast( help_topic_id AS signed) ) DAY ) ,‘%Y-%m-%d’ ) FROM mysql.help_topic WHERE help_topic_id < DAY ( curdate( ) …

示例说明 Makefile 中的 $(@F),及其用法示例$$dir $@ $< $^ %.c

备忘一个不错的开源编辑器CudaText 下载网址&#xff1a; CudaText - Browse /release at SourceForge.net CudaText 主页&#xff1a; CudaText - Home 1&#xff0c;含义及验证 在 Makefile 中&#xff0c;$(F) 表示当前规则的目标文件名&#xff08;不包括路径部分&…

在Linux中使用Apache HTTP服务器

Apache HTTP服务器&#xff0c;也被称为Apache&#xff0c;是全球使用最广泛的Web服务器软件之一。它以其稳定性、强大的功能和灵活性而闻名&#xff0c;尤其在Linux操作系统上表现得尤为出色。以下是关于如何在Linux中使用Apache HTTP服务器的详细指南。 1. 安装Apache 首先…

AI墨墨交流群正式成立:探索科技前沿,共建智能未来

在这个充满变革的时代&#xff0c;AI技术正如涌泉般迸发&#xff0c;带来无限可能。我们深感&#xff0c;唯有汇聚智慧&#xff0c;方能更好地驾驭这股前沿科技的潮流。因此&#xff0c;我们自豪地宣布&#xff1a;AI墨墨交流群正式成立了&#xff01;这不仅是一个交流群&#…

日志系统一(elasticsearch+filebeat+logstash+kibana)

目录 一、es集群部署 安装java环境 部署es集群 安装IK分词器插件 二、filebeat安装&#xff08;docker方式&#xff09; 三、logstash部署 四、kibana部署 背景&#xff1a;因业务需求需要将nginx、java、ingress日志进行收集。 架构&#xff1a;filebeatlogstasheskib…

debug OpenBLAS library 和 应用示例

1. 构建openblas lib git clone gitgithub.com:OpenMathLib/OpenBLAS.git cd OpenBLAS/ 如果要安装在自定义文件夹中&#xff0c;可以修改 PREFIX 的定义&#xff1a; 将 PREFIX /opt/OpenBLAS 修改成 PREFIX ../local/ 然后构建&#xff1a; make -j make install 如果要…

【解决】Unity Project 面板资源显示丢失的异常问题处理

开发平台&#xff1a;Unity 2021.3.7f1c1   一、问题描述 在开发过程中&#xff0c;遭遇 Project 面板资源显示丢失、不全的问题。但 Unity Console 并未发出错误提示。   二、解决方案&#xff1a;删除 Library 目录 前往 “工程目录/Library” 删除内部所有文件并重打开该…

007-可调脉冲数触发之FPGA实现(Zynq也可驱动,带启动停止及完成中断输出)

文章目录 前言一、设计思路二、代码及仿真1.资源消耗2.具体代码3.仿真波形 总结 前言 此代码是在做显微镜高速聚焦系统中自己写的步进电机电机驱动源码&#xff0c;为了达到最快的驱动速度&#xff0c;因此选用脉冲触发方式进行驱动。在电机驱动的过程中往往需要对脉冲进行使能…

React Native 桥接原生实现 JS 调用原生方法

一、为什么需要桥接原生 为了满足在React 层无法实现的需求 复杂高性能的组件&#xff1a;复杂表格、视频播放原生层开发能力&#xff1a;传感器编程、widget平台属性&#xff1a;系统信息、设备信息对接第三方应用&#xff1a;相机、相册、地图 真实的开发过程中是不可能完…

OpenGL学习笔记-Blending

混合方程中&#xff0c;Csource是片段着色器输出的颜色向量&#xff08;the color output of the fragment shader&#xff09;&#xff0c;其权重为Fsource。Cdestination是当前存储在color buffer中的颜色向量&#xff08;the color vector that is currently stored in the …

欢乐的周末 - 华为OD统一考试

OD统一考试 题解&#xff1a; Java / Python / C 题目描述 小华和小为是很要好的朋友&#xff0c;他们约定周末一起吃饭。 通过手机交流&#xff0c;他们在地图上选择了多个聚餐地点(由于自然地形等原因&#xff0c;部分聚餐地点不可达)。求小华和小为都能到达的聚餐地点有多…

私域爆款活动实操指南,让你轻松成为营销高手!

私域运营活动是公司运营中非常重要的一环&#xff0c;它能够提高用户参与度、增加用户忠诚度&#xff0c;并为公司带来更多的商业机会。然而&#xff0c;策划和执行一场成功的私域运营活动并不容易&#xff0c;需要思维缜密、部门合作以及落地能力等方面的综合素养。今天来跟大…

Orchestrator源码解读2-故障失败发现

目录 前言 核心流程函数调用路径 GetReplicationAnalysis 故障类型和对应的处理函数 ​编辑 拓扑结构警告类型 核心流程总结 与MHA相比 前言 Orchestrator另外一个重要的功能是监控集群&#xff0c;发现故障。根据从复制拓扑本身获得的信息&#xff0c;它可以识别各种故…

JDK21和 Flowable 7.0.0

JDK21和 Flowable 7.0.0 一.Flowable二.项目搭建1.依赖包2.数据库3.资源文件1.YML配置文件2.Drools kbase3.Drools rule4.DMN 决策表5.BPMN 流文件 4.BPMN 流程图绘制插件5.测试代码1.启动类2.Flowable 配置3.Camel 配置1.Camel 配置2.Camel Router 定义 4.扩展类监听1.外部工作…

【MySQL】视图,15道常见面试题---含考核思路详细讲解

目录 一 视图 1.1视图是什么 1.2 创建视图 1.3 查看视图(两种) 1.4 修改视图(两种) 1.5 删除视图 二 外连接&内连接&子查询介绍 2.1 外连接 2.2 内连接 2.3 子查询 三 外连接&内连接&子查询案例 3.1 了解表结构与数据 3.2 15道常见面试题 四 思…