【react】特种兵之react.tsx列表页面搭建

news2024/11/27 10:27:21

目录

    • 背景
    • 了解工程架构
    • 我可开始了啊
      • 新建一个页面
        • 怎么写?
        • 前端代码编写思路
    • 感触

背景

方便系统运维、不用每次初始化数据都走数据订正

这是第一次毕业之后,用前端语言新建一个页面,过程自然是极其曲折。情绪也是跌宕起伏,从页面显示到数据展渲染展示,每次成功完成一个功能点,内心的喜悦值都上升一个点。当然脑花拧成团,甚至打结也难以知道怎么开发,代码怎么写。开发页面过程中,多次向前端同学请教,也多次借助GPT,帮助我熟悉React的语法格式。本来大学前端网课就一节没听,全靠特种兵之0基础的勇气 (不是,疫情期间谁在家学网课啊 )。好在结果是好的,历时四天-前后端都开发完成✅,新技能即将get (一点点皮毛)~~

了解工程架构

Study
-moke
--index.js

-src
--config
---routes.js

--pages
---Calendar
----index.js

--services
---calendar.js

moke 包用来moke后端接口返回的数据
config包用来写整个工程的页面路由
pages包用来写整个工程的所有页面代码
services包用来写后端接口的请求路径

我可开始了啊

了解一些前端相关知识:
–npm (和后端的maven差不多,管理依赖的一个工具)
–node.js(相当于一个运行环境和后端的javac差不多)
–tsx、jsx为React页面文件类型
(初次了解只知道tsx可以和react很好的扩展语法,更好的实现前端页面。)

GPT官方回答

npm(Node Package Manager)是 Node.js 的包管理器,它允许开发者轻松共享和重复使用代码,以及安装和管理依赖项。npm 也提供了一个终端命令行工具,可以方便地安装、升级、卸载和搜索包。

Node.js 是一个运行 JavaScript 的开源环境,它使用了 Chrome V8 引擎来解析和执行 JavaScript 代码。Node.js 具有事件驱动、非阻塞 I/O 和单线程等特点,使得它能够高效地处理大量并发请求。Node.js 可以用于构建服务器端应用程序、命令行工具和桌面应用程序等。

TSX是TypeScript XML的缩写,它是一种在React应用中使用TypeScript的语法扩展。TSX扩展了JSX语法,使得React组件可以使用TypeScript进行类型检查,提高了代码的可靠性和可维护性。

JSX是一种JavaScript的语法扩展,它被React用于描述UI组件的结构和行为。而TSX通过在JSX中添加类型注解,使得React组件的Props和State等属性可以进行类型检查,从而避免了许多类型错误。

TSX的使用需要先安装TypeScript,并在项目中配置相应的TSX编译器。常见的TSX编译器有babel、ts-loader等。

新建一个页面

在pages下新建一个包 Calendar,新建一个文件index.tsx。

怎么写?

第一步先把页面各部分架子搭起来

const IndexPage = () => {
// 定义列头

// 渲染页面数据

return(
// 前端页面代码
)
};
export default IndexPage;

第二步先把页面渲染出来,后面会分步解释

import * as React from 'react';
import {
  ProTable,
  useProTable,
  PageHeader,
  Page,
  Card,
  CardSection,
  Filter,
  ProFormItem,
  Select,
  ProTableRowSelectionInstance,
  ProTableColumnProps,
  Dialog,
  Message,
  Input,
  ProForm,
} from '@alife/whale-ui';
import request from '@alife/whale-request';
import { useRef, useState } from 'react';
import { getList } from '@/services/calendar';

class Props {
  /**
   * id
   */
  id: bigint;

  /**
   * 类别编码
   */
  categoryCode: String;

  /**
   * 帐期
   */
  accountingPeriod: String;

  /**
   * 帐期编码
   */
  code: String;

  /**
   * 月结日期
   */
  date: String;

  /**
   * 描述
   */
  description: String;
};

const IndexPage = () => {
  const rowSelectionRef = useRef<ProTableRowSelectionInstance>();
  const [editVisible, setEditVisible] = useState(false);
  const [formInfo, setFormInfo] = useState<Props>();
  const [isEdit, setIsEdit] = useState(false);

  // 定义列头
  const columns: ProTableColumnProps[] = React.useMemo(
    () => [
      {
        dataIndex: 'categoryCode',
        width: 60,
        align: 'left',
        title: '类别编码',
      },
      {
        dataIndex: 'code',
        width: 80,
        align: 'left',
        title: '帐期编码 ',
      },
      {
        dataIndex: 'accountingPeriod',
        width: 80,
        align: 'left',
        title: '帐期',
      },
      {
        dataIndex: 'date',
        align: 'left',
        width: 100,
        title: '对应日期',
        formatType: 'date',
      },
      {
        dataIndex: 'description',
        width: 100,
        align: 'left',
        title: '描述',
      },
    ],
    [],
  );

  // 渲染页面数据
  const { tableProps, filterProps, refresh } = useProTable(
    // 请求后端数据
    getList(),
    {
      onParamsChange: () => {
        // 当参数改变时清空选中行
        rowSelectionRef.current &&
        rowSelectionRef.current.selectAllPages(false);
      },
    },
  );

  return (
    <Page>
      <PageHeader
        breadcrumbProps={{
          dataSource: [
            { children: '月结日历-特殊日期' },
            { children: '月结日历列表' },
          ],
        }}
      />

      <Page>
        <Dialog cardMode title={isEdit ? '编辑数据' : '新增数据'} visible={editVisible}
                onClose={() => {
                  setEditVisible(false);
                  setFormInfo(undefined);
                }}
                onCancel={() => {
                  setEditVisible(false);
                  setFormInfo(undefined);
                }}
                onOk={() => {
                  request({
                    url: `/caijing-ops/api/calendar/special/day/createOrUpdate`,
                    method: 'POST',
                    data: {
                      id: formInfo.id,
                      categoryCode: formInfo.categoryCode,
                      accountingPeriod: formInfo.accountingPeriod,
                      code: formInfo.code,
                      date: formInfo.date,
                      description: formInfo.description,
                    },
                  }).then(() => {
                    Message.success(isEdit ? '编辑成功' : '新增成功');
                    setFormInfo(undefined);
                  });
                  setEditVisible(false);
                }}
        >
          <Card segmentLine>
            <CardSection>
              <ProForm isPreview layoutMode='responsive' value={formInfo}>
                <ProFormItem isPreview={false} required={true} colSpan={1} label='类别编码'>
                  <Select name='categoryCode' defaultValue={'MEC'} hasSelectAll showSearch
                          dataSource={[
                            {
                              label: 'MEC',
                              value: 'MEC',
                            },
                            {
                              label: 'ANT',
                              value: 'ANT',
                            },
                          ]} />
                </ProFormItem>
                <ProFormItem isPreview={false} colSpan={1} label='帐期' explanation={'格式为 年份-月份 eg:2023-01'}>
                  <Input name={'accountingPeriod'} />
                </ProFormItem>
                <ProFormItem isPreview={false} colSpan={1} label='帐期编码' explanation={'格式为 类别_D? eg:MEC_D1'}>
                  <Input name={'code'} />
                </ProFormItem>
                <ProFormItem isPreview={false} colSpan={1} label='月结日期' explanation={'格式为 年-月-日? eg:2023-03-01'}>
                  <Input name={'date'} />
                </ProFormItem>
                <ProFormItem isPreview={false} colSpan={1} label='描述' explanation={'格式为 年-月 月结D? eg:2023-01 月结D1'}>
                  <Input name={'description'} />
                </ProFormItem>
              </ProForm>
            </CardSection>
          </Card>
        </Dialog>
      </Page>
      <Card segmentLine={true}>
        <CardSection>
          <Filter enableForm enableFilterConfiguration {...filterProps}>
            <ProFormItem label='类别'>
              <Select name='categoryCode' defaultValue={'MEC'} hasSelectAll showSearch
                      dataSource={[
                        {
                          label: 'MEC',
                          value: 'MEC',
                        },
                        {
                          label: 'ANT',
                          value: 'ANT',
                        },
                      ]}
              />
            </ProFormItem>
            <ProFormItem label='帐期'>
              <Select name='accountingPeriod' showSearch filterLocal={false} requestConfig={{
                service: ({ params }) => ({
                  url: '/caijing-ops/api/calendar/special/day/selectCode',
                  method: 'GET',
                  params,
                }),
              }}
              />
            </ProFormItem>
            <ProFormItem label='帐期编码'>
              <Select name='code' showSearch filterLocal={false} requestConfig={{
                service: ({ params }) => ({
                  url: '/caijing-ops/api/calendar/special/day/selectAccountingPeriod',
                  method: 'GET',
                  params,
                }),
              }}
              />
            </ProFormItem>
          </Filter>
        </CardSection>
        <CardSection>
          <ProTable
            columns={columns}
            {...tableProps}
            actionBarButtons={{
              dataSource: [
                {
                  children: '新增',
                  type: 'primary',
                  onClick: (e, payload) => {
                    setEditVisible(true);
                  },
                },
              ],
            }}
            actionColumnButtons={{
              dataSource: [
                {
                  children: '编辑',
                  type: 'primary',
                  onClick: (e, payload) => {
                    setEditVisible(true);
                    setIsEdit(true);
                    setFormInfo({
                      id: payload.rowRecord.id,
                      categoryCode: payload.rowRecord.categoryCode,
                      accountingPeriod: payload.rowRecord.accountingPeriod,
                      code: payload.rowRecord.code,
                      date: payload.rowRecord.date,
                      description: payload.rowRecord.description,
                    });
                    console.log(formInfo);
                  },
                },
                {
                  children: '删除',
                  onClick: (e, payload) => {
                    Dialog.confirm({
                      title: `是否确认删除 "${payload.rowRecord.description}"数据?`,
                      onOk: () => {
                        request({
                          url: `/caijing-ops/api/calendar/special/day/delete?id=${payload.rowRecord.id}`,
                          method: 'GET',
                        }).then(() => {
                          Message.success('删除成功');
                          refresh(); // 使用 refresh 刷新当前页
                        });
                      },
                    });
                  },
                },
              ],
            }}
          />
        </CardSection>
      </Card>;
    </Page>
  )
    ;
};

export default IndexPage;

routes.js 此处定义的是前端路由

const CalendarSpecialDayList = React.lazy(() => import('@/pages/Calendar/ListPage'));

const routerConfig=[
  {
    path: '/operation',
    title: '运维管理',
    component: Layout,
    children: [
      {
        path: '/list',
        title: '月结日历运维',
        component: CalendarSpecialDayList,
      }
    ],
  },
]

export default routerConfig;

calendar.js 此处为后端接口路径

export function getList() {
  return async ({ current, pageSize, filterParams }) => {
    const res = await request({
      url: `/list`,
      method: 'POST',
      data: {
        accountingPeriod: filterParams.accountingPeriod,
        code: filterParams.code,
        pageNum: current,
        pageSize: pageSize,
      },
      crossOrigin: true,
    });
    return {
      total: res.count,
      dataSource: res.data,
    };
  };
}

前端代码编写思路

1.设置 Dialog弹窗状态,初始化关闭,在点击新增/编辑时更新为true

  const [editVisible, setEditVisible] = useState(false);

2.设置 编辑弹窗内的数据值,用于回显数据
3.在点击确定、取消时关闭弹窗(即把 Dialog弹窗状态update即可)
在这里插入图片描述
4.在定义回显数据时,先定义一个类

class Props {
  /**
   * id
   */
  id: bigint;

  /**
   * 类别编码
   */
  categoryCode: String;

  /**
   * 帐期
   */
  accountingPeriod: String;

  /**
   * 帐期编码
   */
  code: String;

  /**
   * 月结日期
   */
  date: String;

  /**
   * 描述
   */
  description: String;
};
 const [formInfo, setFormInfo] = useState<Props>();

5.Get/Post如何传参
post传参为JSON格式

url: `/list`,
      method: 'POST',
      data: {
        accountingPeriod: filterParams.accountingPeriod,
        code: filterParams.code,
        pageNum: current,
        pageSize: pageSize,
      },

GET传参为拼接URL方式

  url: `/delete?id=${payload.rowRecord.id}`,
  method: 'GET',

感触

前后端交互逻辑独立熟悉编写,感觉react和Java逻辑编写时类似。希望以后能进一步学习,由简到杂,向全栈进军!

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

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

相关文章

无需代理客户端,轻松实现虚拟机备份!

21世纪的虚拟化技术为企业提供了极大的便利和成本节约。它允许企业通过管理程序创建虚拟机以在单个主机上运行多个不同的操作系统&#xff0c;从而充分利用计算资源并节省架构和管理成本。 随着组织将其业务迁移到虚拟化平台&#xff0c;执行数据保护的方法也随之改变。虚拟机…

重视企业缺少成本票问题!合理利用税收优惠政策降低企业所得税!

重视企业缺少成本票问题&#xff01;合理利用税收优惠政策降低企业所得税&#xff01; 业务是流程&#xff0c;财税是结果&#xff0c;税收问题千千万&#xff0c;关注《税算盘》来帮你找答案。 很多企业在成立的初期会出现对票据管理不严格的情况&#xff0c;前期影响也不是…

精选博客系列|VMware Tanzu Mission Control增强策略功能,让Kubernetes的安全性更加灵活

随着分布式系统日益复杂&#xff0c;定义和实施 Kubernetes 集群的策略以确保环境的安全性、可靠性和合规性 —— 当然也是为了构建可扩展性的支撑结构&#xff0c;变得至关重要。 因此&#xff0c;我们很高兴宣布 VMware Tanzu Mission Control 现在有了更多的策略相关的改进…

C# webservice 接收json数据 接口返回 远程服务器返回错误: (500) 内部服务器错误

C# post 调用webservice 服务端接口&#xff0c;会返回上面那个错误&#xff0c;8成是发送的数据和接口不符合造成的。有2种情况 第一种情况如下&#xff1a;如果类型是默认request.ContentType "application/x-www-form-urlencoded";这个类型 那么你发送数据和被…

基于趋动云部署B站大V秋葉aaaki的Stable Diffusion整合包v4--linux版

B站大V秋葉aaaki的Stable Diffusion整合V4版发布了&#xff0c;集成度比较高&#xff0c;在windows下解压缩直接就可以使用&#xff0c;整合的非常好。但是笔人没有RTX4090这样级别的显卡&#xff0c;又希望有个高速运行的效果。 所以索性到云GPU主机上来用秋叶aaaki的Stable …

windows机制初探

Windows内存管理 EPROCESS结构体&#xff1a;在内核中表示一个进程 VAD树 二叉树&#xff0c;存储进程在内核层申请的虚拟内存信息 (x86 EPROCESS0x11c) (x64 EPROCESS0x7d8)指向VadRoot(VAD树) 可以看到两种内存&#xff1a;Private(私有内存)、 Mapped(映射内存) 私有内…

Elasticsearch 入门

Elasticsearch 是一种开源搜索引擎&#xff0c;它基于 Apache Lucene 构建&#xff0c;提供了一个分布式、多租户、全文搜索和分析引擎。Elasticsearch 可以处理海量数据&#xff0c;能够快速、准确地搜索、分析和可视化数据。 Elasticsearch 最初是为了解决日志搜索和分析而开…

2018年下半年 软件设计师 答案及详解

2018年下半年 软件设计师 答案详解 主要记录刷题相关笔记&#xff0c;方便日后温习&#xff01;&#xff01;&#xff01; 一、选择题 CPU 在执行指令的过程中&#xff0c;会自动修改_____的内容&#xff0c;以使其保存的总是将要执行的下一条指令的地址。 A.指令寄存器B.程…

makefile 变量的扩展

文章目录 前言一、环境变量&#xff08;全局变量&#xff09;二、目标变量&#xff08;局部变量&#xff09;三、模式变量总结 前言 一、环境变量&#xff08;全局变量&#xff09; Makefile 中的环境变量&#xff0c;是指在执行 Makefile 时&#xff0c;从外部传入 Make 命令…

m4a音频怎么转换成mp3?

m4a音频怎么转换成mp3&#xff1f;如果你遇到了m4a音频格式的文件&#xff0c;但却无法在音频播放器中打开它&#xff0c;通常我们会将其转换成mp3格式。因为M4A属于苹果专用的音频格式&#xff0c;而MP3则是一种通用音频格式。M4A属于高品质压缩类型的音乐文件&#xff0c;而M…

Django框架之使用Session保持HTTP状态

HTTP协议是无状态的&#xff0c;每次请求都是新的请求&#xff1b; 客户端与服务器端的一次通信就是一次会话。 可使用cookie和session在客户端或者服务端存储有关会话的数据&#xff0c;来进行状态保持&#xff1b; cookie使用在上篇。本篇是使用session进行状态保持及使用Red…

外观数列----2023/5/11

外观数列----2023/5/11 给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) “1”…

Omniverse Replicator环境配置和使用说明

Omniverse Replicator使用说明 本教程将介绍Omniverse Replicator的环境配置和使用说明, 参加Sky Hackathon的同学可以参考本教程来合成训练数据集. 文章目录 Omniverse Replicator使用说明1. Omniverse环境配置1.a.安装Omniverse Launcher1.a.1.在下面的地址下载Omniverse La…

案例分享:ChatGPT写python脚本,轻松文本处理

大家好&#xff0c;我是可夫小子&#xff0c;关注AIGC、读书和自媒体。解锁更多ChatGPT、AI绘画玩法。加&#xff1a;keeepdance&#xff0c;备注&#xff1a;chatgpt&#xff0c;拉你进群。 在工作中&#xff0c;需要对数据进行筛选、分割和整理&#xff0c;当你接受到一个长长…

浅谈Android PMS解析APP信息流程

前言 前面我们了解了Zygote的启动流程&#xff0c;知道AMS、PMS都是由SystemServer进程启动的&#xff0c;我们都知道PMS主要负责App管理工作&#xff0c;这里我们简单从源码角度分析下PMS是如何解析APP解析的&#xff1b; 源码分析(API 30为例) 我们还是从PackageManagerSe…

SpringBoot缓存技术详解

文章目录 一、 缓存技术介绍1. 缓存技术简介2. JSR107核心接口3. JSR107 图示3. SpringBoot缓存抽象4. 缓存常用注解和接口 一、 缓存技术实战1. Cacheable注解2. 缓存的工作原理4. Cacheable注解的工作流程 一、 缓存技术介绍 1. 缓存技术简介 缓存技术主要分为两大类缓存可…

6 进程的环境

6.1 main函数 C程序总是从main函数开始执行。main函数的原型是&#xff1a; int main(int argc, char *argv[]) 6.2 进程终止 有五种方式使进程终止&#xff1a; &#xff08;1&#xff09;正常终止&#xff1a; &#xff08;a&#xff09;从main返回。 &#xff08;b&…

Pycharm十种不为人所知的技巧,不得不知道

Pycharm是Python语言开发中的一个非常强大的IDE工具&#xff0c;其高度的定制能力、日常开发中常用的工具和各种快捷键等功能&#xff0c;都能帮助Pycharm用户提高开发效率。但是&#xff0c;Pycharm中的许多功能并不为人所知。因此&#xff0c;以下是十种Pycharm技巧&#xff…

【MCS-51】51单片机指令系统大全

指令是指挥微型计算机工作的的计算机命令&#xff0c;对于51单片机来说&#xff0c;其主要使用的指令有两种形式&#xff1a;机器语言指令和汇编语言指令。 机器语言指令是指使用二进制代码表示的指令&#xff1b; 汇编语言指令是指使用容易我们记忆的缩写符号表示的机器语言…

YOLO入门指南:理解YOLO原理及构建第一个目标检测模型

YOLO&#xff08;You Only Look Once&#xff09;是一种快速且准确的目标检测算法&#xff0c;可以在图像或视频中检测出多个对象的位置和类别。在本篇文章中&#xff0c;我们将介绍YOLO的基本原理&#xff0c;并使用TensorFlow构建第一个目标检测模型。 YOLO的基本原理 YOLO的…