Umi的学习之路

一、介绍umi Umi官网:https://umijs.org/ Umi 是蚂蚁金服的底层前端框架(经蚂蚁内部 3000+ 项目验证) Umi 是以'路由'为基础的企业级React框架(同时支持配置式路由和约定式路由) Umi 是一个'可插拔'的企业级React框架(内部功能完全使用插件化完成) 总

一、介绍umi

Umi官网:https://umijs.org/

  • Umi 是蚂蚁金服的底层前端框架(经蚂蚁内部 3000+ 项目验证)
  • Umi 是以'路由'为基础的企业级React框架(同时支持配置式路由和约定式路由)
  • Umi 是一个'可插拔'的企业级React框架(内部功能完全使用插件化完成)
  • 总结就是 Umi 是一个蚂蚁金服底层的, 以'路由'为基础的, 内部功能完全使用插件化完成的 React 框架

在这里怎么创建以及启动就不赘述了,官网已经有教程了,按照要求来即可。

二、Umi的目录结构

├── config // 配置文件
│ └── config.ts
├── dist
├── mock // 模拟请求
│ └── app.ts|tsx
├── src
│ ├── .umi
│ ├── .umi-production
│ ├── layouts // 页面框架
│ │ ├── BasicLayout.tsx
│ │ ├── index.less
│ ├── models // 全局模块
│ │ ├── global.ts
│ │ └── index.ts
│ ├── pages // 页面
│ │ ├── index.less
│ │ └── index.tsx
│ ├── utils // 推荐目录
│ │ └── index.ts
│ ├── services // 推荐目录
│ │ └── api.ts
│ ├── app.(ts|tsx)
│ ├── global.ts
│ ├── global.(css|less|sass|scss)
│ ├── overrides.(css|less|sass|scss)
│ ├── favicon.(ico|gif|png|jpg|jpeg|svg|avif|webp)
│ └── loading.(tsx|jsx)
├── node_modules // 无需介绍
│ └── .cache
│ ├── bundler-webpack
│ ├── mfsu
│ └── mfsu-deps
├── .env // 环境配置
├── plugin.ts // 插件配置
├── .umirc.ts // 与 config/config 文件 2 选一
├── package.json // 无需介绍
├── tsconfig.json // 无需介绍
└── typings.d.ts // 无需介绍

在这里使用Umimax框架,基于react和antd pro框架

因此,在学习UmiMax框架的同时,还需要数据antd pro框架的封装思想。

Ant Design Pro : https://pro-components.antdigital.dev/

简介:重型组件区别于传统组件有个很大的不同,重型组件在抽象时是将其当成一个页面来进行处理,所以 ProTable 会支持网络请求和自动生成查询表单,而 ProLayout 会支持自动生成菜单,两者都基于同样的思想也就是提供页面级别的抽象。

一个列表页应该可以用 ProLayout + ProTable 完成,一个编辑页应该使用 ProLayout + ProForm 完成,详情页可以用 ProLayout + ProDescriptions 完成。 一个页面在开发过程中只需要关注几个重型组件,降低心智负担,专注于更核心的业务逻辑。

创建页面

按照 Umi 的命名规范,在 pages 中创建目录,例如我现在需要一个产品管理页面

  • 创建 Production 目录;
  • 在 Productiion 目录下搭建页面
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { PageContainer, ProTable } from '@ant-design/pro-components';
import { Button } from 'antd';
import React, { useRef, useState } from 'react';
import CreateOrEdit from './Modal';
const data = [
  {
    id: 1,
    name: '1111',
    info: '这是一条产品信息',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料',
  },
  {
    id: 2,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 3,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 4,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 5,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 6,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 7,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 8,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 9,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 10,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
  {
    id: 11,
    name: '2222',
    info: '这是一条产品信息2',
    img: 'http://abc.ariessui.asia/EEE6269F-963A-4137-994E-E9EE455A595C_1_105_c.jpeg',
    material: '材料2',
  },
];
const ProductionPage: React.FC = () => {
  type TableListItem = {
    id: number;
    name: string;
    info: string;
    img: string;
    material: string;
  };
  const actionRef = useRef<ActionType>();
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [forms, setForms] = useState({});
  //控制模态框显示隐藏
  const isShowModal = (show: boolean, forms?: any) => {
    console.log(forms);

    setForms(forms);
    setIsModalVisible(show);
  };
  const columns: ProColumns<TableListItem>[] = [
    {
      title: 'ID',
      dataIndex: 'id',
      ellipsis: true,
      align: 'center',
      search: false,
      width: '50',
    },
    {
      title: '图片预览',
      align: 'center',
      search: false,
      render: (_, row) => {
        return <img src={row.img} width={100}></img>;
      },
    },
    {
      title: '产品名称',
      dataIndex: 'name',
      align: 'center',
      search: true,
    },
    {
      title: '图片',
      dataIndex: 'img',
      align: 'center',
      search: false,
    },

    {
      title: '产品信息',
      dataIndex: 'info',
      align: 'center',
      search: false,
    },
    {
      title: '产品材料',
      dataIndex: 'material',
      align: 'center',
      search: false,
    },

    {
      title: '操作',
      valueType: 'option',
      render: (text, record, _, action) => [
        <a
          key="editable"
          onClick={() => {
            isShowModal(true, record);
          }}
        >
          编辑
        </a>,
      ],
    },
  ];

  //   function queryCustomer(
  //     params: import('@ant-design/pro-provider').ParamsType & {
  //       pageSize?: number | undefined;
  //       current?: number | undefined;
  //       keyword?: string | undefined;
  //     },
  //   ): any {
  //     throw new Error('Function not implemented.');
  //   }
  const handleClickCreate = () => {
    isShowModal(true, {});
  };

  return (
    <PageContainer ghost>
      <ProTable<TableListItem>
        rowKey="id"
        actionRef={actionRef}
        columns={columns}
        headerTitle="全部数据"
        dataSource={data}
        search={{
          labelWidth: 'auto',
        }}
        pagination={{
          showQuickJumper: true,
        }}
        toolBarRender={() => [
          <Button
            type="primary"
            key="create"
            onClick={() => handleClickCreate()}
          >
            添加
          </Button>,
        ]}
        params={{ page: 'MY' }}
        // request={async (params = {}) => {
        //   const response = (await queryCustomer(params)) as any;
        //   const {
        //     data: { data, total },
        //     success,
        //   } = response;
        //   return {
        //     data,
        //     total,
        //     success,
        //   };
        // }}
      />
      {!isModalVisible ? (
        ''
      ) : (
        <CreateOrEdit
          isModalVisible={isModalVisible}
          isShowModal={isShowModal}
          actionRef={actionRef}
          forms={forms}
        />
      )}
    </PageContainer>
  );
};

export default ProductionPage;
  • 创建 Modal 框组件:在 Production 页面下面创建 Modal 目录
// import { addUser, showUser, updateUser } from '@/services/user';
import ProForm, { ProFormText } from '@ant-design/pro-form';
import { Modal } from 'antd';
import { useState } from 'react';
const CreateOrEdit = (props: any) => {
  const { isModalVisible } = props;
  const { isShowModal } = props;
  const { actionRef } = props;
  const { forms } = props;
  const [initialValues, setInitialValues] = useState(forms);

  const title = forms.id === undefined ? '添加产品信息' : '编辑产品信息';
  //定义form实例用来操作表单
  const [formObj] = ProForm.useForm();
  const createUser = async (values: any) => {
    console.log(values);
    // message.success('提交成功');
    if (title == '添加产品信息') {
      //   const response = await addUser(values);
      //   if (response.status === undefined) {
      //     message.success('添加成功');
      //     //刷新表格数据
      //     actionRef.current?.reload();
      //     isShowModal(false);
      //   }
      // const responses = await updateAvatar({avatar:values.avatar})
      // console.log('头像responses:',responses);
    } else {
      //   const response = await updateUser(editId, values);
      //   if (response.status === undefined) {
      //     message.success('修改成功');
      //     //刷新表格数据
      //     actionRef.current?.reload();
      //     formObj.resetFields();
      //     isShowModal(false);
      //   }
    }
  };

  return (
    <Modal
      title={title}
      open={isModalVisible}
      footer={null}
      onCancel={() => isShowModal(false)}
      destroyOnClose={true}
    >
      <ProForm
        form={formObj}
        initialValues={initialValues}
        onFinish={(values) => createUser(values)}
      >
        <ProFormText
          name="name"
          label="产品名称"
          placeholder="请输入产品名称"
          rules={[
            {
              required: true,
              message: '请输入产品名称',
            },
          ]}
        />
        <ProFormText
          name="img"
          label="图片地址"
          placeholder="请输入图片地址"
          rules={[
            {
              required: true,
              message: '请输入图片地址',
            },
          ]}
        />
        <ProFormText
          name="info"
          label="产品信息"
          placeholder="请输入产品信息"
          rules={[
            {
              required: true,
              message: '请输入产品信息',
            },
          ]}
        />
        <ProFormText
          name="material"
          label="产品材料"
          placeholder="请输入产品材料"
          rules={[
            {
              required: true,
              message: '请输入产品材料',
            },
          ]}
        />
      </ProForm>
    </Modal>
  );
};

export default CreateOrEdit;

到这里,一个简单的页面就创建好了,还需要的就是对接 CRUD 接口

LICENSED UNDER CC BY-NC-SA 4.0
Comment