- ant design pro 如何去保存颜色
- ant design pro v6 如何做好角色管理
- ant design 的 tree 如何作为角色中的权限选择之一
- ant design 的 tree 如何作为角色中的权限选择之二
- ant design pro access.ts 是如何控制多角色的权限的
- ant design pro 中用户的表单如何控制多个角色
- ant design pro 如何实现动态菜单带上 icon 的
- ant design pro 的表分层级如何处理
- ant design pro 如何处理权限管理
- ant design pro 技巧之自制复制到剪贴板组件
像上图那样,我们经常给列表页做分类的,
这种多标签如何处理呢?
肯定是要得到动态数据对吧。
每次点击的时候要发请求,得到不同的数据。
其实 ant design pro 是支持的。
在 index.tsx 中的 protable 里加上这个就好。
toolbar={{menu: {type: 'tab',activeKey: activeKey,items: [{label: <FormattedMessage id="platform.all" defaultMessage="All" />,key: '',},{label: <FormattedMessage id="platform.online" defaultMessage="Online" />,key: 'true',},{label: <FormattedMessage id="platform.offline" defaultMessage="Offline" />,key: 'false',},],onChange: (key: any) => {setActiveKey(key);if (actionRef.current) {actionRef.current.reload();}},},}}
完整代码是这样的:
import { addItem, queryList, removeItem, updateItem } from '@/services/ant-design-pro/api';
import { PlusOutlined } from '@ant-design/icons';
import type { ActionType, ProColumns, ProDescriptionsItemProps } from '@ant-design/pro-components';
import { FooterToolbar, PageContainer, ProTable } from '@ant-design/pro-components';
import { FormattedMessage, useAccess } from '@umijs/max';
import { Button, message, Modal, Switch, Tooltip } from 'antd';
import React, { useRef, useState } from 'react';
import type { FormValueType } from './components/Update';
import Update from './components/Update';
import Create from './components/Create';
import Show from './components/Show';
import { useIntl } from '@umijs/max';
import { carTypeMap } from '@/utils/constants';
import CopyToClipboard from '@/components/CopyToClipboard';
import ConfigureForm from './components/ConfigureForm';/*** @en-US Add node* @zh-CN 添加节点* @param fields*/
const handleAdd = async (fields: API.ItemData) => {const hide = message.loading(<FormattedMessage id="adding" defaultMessage="Adding..." />);try {await addItem('/platforms', { ...fields });hide();message.success(<FormattedMessage id="add.success" defaultMessage="Added successfully" />);return true;} catch (error: any) {hide();message.error(error?.response?.data?.message ?? (<FormattedMessage id="add.failed" defaultMessage="Adding failed, please try again!" />),);return false;}
};/*** @en-US Update node* @zh-CN 更新节点** @param fields*/
const handleUpdate = async (fields: FormValueType) => {const hide = message.loading(<FormattedMessage id="updating" defaultMessage="Updating..." />);try {await updateItem(`/platforms/${fields._id}`, fields);hide();message.success(<FormattedMessage id="update.success" defaultMessage="Updated successfully" />);return true;} catch (error: any) {hide();message.error(error?.response?.data?.message ?? (<FormattedMessage id="update.failed" defaultMessage="Update failed, please try again!" />),);return false;}
};/*** Delete node* @zh-CN 删除节点** @param selectedRows*/
const handleRemove = async (ids: string[]) => {const hide = message.loading(<FormattedMessage id="deleting" defaultMessage="Deleting..." />);if (!ids) return true;try {await removeItem('/platforms', {ids,});hide();message.success(<FormattedMessageid="delete.success"defaultMessage="Deleted successfully and will refresh soon"/>,);return true;} catch (error: any) {hide();message.error(error.response.data.message ?? (<FormattedMessage id="delete.failed" defaultMessage="Delete failed, please try again" />),);return false;}
};const TableList: React.FC = () => {const intl = useIntl();/*** @en-US Pop-up window of new window* @zh-CN 新建窗口的弹窗* */const [createModalOpen, handleModalOpen] = useState<boolean>(false);/**2024fc.xyz* @en-US The pop-up window of the distribution update window* @zh-CN 分布更新窗口的弹窗* */const [updateModalOpen, handleUpdateModalOpen] = useState<boolean>(false);const [showDetail, setShowDetail] = useState<boolean>(false);const actionRef = useRef<ActionType>();const [currentRow, setCurrentRow] = useState<API.ItemData>();const [selectedRowsState, setSelectedRows] = useState<API.ItemData[]>([]);const access = useAccess();const [activeKey, setActiveKey] = useState<string | undefined>('');const [configureModalVisible, setConfigureModalVisible] = useState<boolean>(false);/*** @en-US International configuration* @zh-CN 国际化配置* */const columns: ProColumns<API.ItemData>[] = [{title: intl.formatMessage({ id: 'platform.name' }),dataIndex: 'name',width: 150,copyable: true,render: (dom, entity) => {return (<aonClick={() => {setCurrentRow(entity);setShowDetail(true);}}>{dom}</a>);},},{title: intl.formatMessage({ id: 'platform.image' }),dataIndex: 'image',width: 100,hideInSearch: true,valueType: 'image',},{title: intl.formatMessage({ id: 'platform.region' }),dataIndex: 'region',width: 200,render: (_, record: any) =>record.region && (<>{record.region.name} <CopyToClipboard text={record.region.name} /></>),},{title: intl.formatMessage({ id: 'platform.price' }),dataIndex: 'price',width: 150,hideInSearch: true,render: (text, record: any) => (<Tooltip title={`€ ${record.priceInEuro}`}><strong>$ {text}</strong>/{carTypeMap[record.carType as keyof typeof carTypeMap]}</Tooltip>),},{title: intl.formatMessage({ id: 'platform.tips' }),ellipsis: true,width: 150,hideInTable: true,hideInSearch: true,dataIndex: 'tips',},{title: intl.formatMessage({ id: 'platform.boardingMethod' }),dataIndex: 'boardingMethod',width: 150,hideInSearch: true,hideInTable: true,valueEnum: {'': { text: intl.formatMessage({ id: 'all' }), status: 'Default' },fullCar: { text: intl.formatMessage({ id: 'platform.fullCar' }) },batchCar: { text: intl.formatMessage({ id: 'platform.batchCar' }) },},},{title: intl.formatMessage({ id: 'platform.deliveryMethod' }),dataIndex: 'deliveryMethod',width: 150,hideInSearch: true,hideInTable: true,valueEnum: {'': { text: intl.formatMessage({ id: 'all' }), status: 'Default' },autoDelivery: { text: intl.formatMessage({ id: 'platform.autoDelivery' }) },inviteLink: { text: intl.formatMessage({ id: 'platform.inviteLink' }) },},},{title: intl.formatMessage({ id: 'platform.status' }),dataIndex: 'isOnline',width: 150,hideInSearch: true,render: (_, record: any) => (<SwitchcheckedChildren={intl.formatMessage({ id: 'platform.online' })}unCheckedChildren={intl.formatMessage({ id: 'platform.offline' })}checked={record.isOnline}onChange={async () => {await handleUpdate({ _id: record._id, isOnline: !record.isOnline });if (actionRef.current) {actionRef.current.reload();}}}/>),},{title: intl.formatMessage({ id: 'platform.remark' }),ellipsis: true,width: 150,hideInSearch: true,dataIndex: 'remark',},{title: intl.formatMessage({ id: 'platform.userCount' }),hideInSearch: true,width: 150,hideInTable: true,dataIndex: 'userCount',},{title: intl.formatMessage({ id: 'platform.user' }),hideInSearch: true,width: 150,dataIndex: 'user',render: (_, record) => record.user && record.user.name,},{title: <FormattedMessage id="creation_time" defaultMessage="Creation Time" />,width: 250,dataIndex: 'createdAt',valueType: 'dateTime',hideInSearch: true,},{title: <FormattedMessage id="platform.description" defaultMessage="platform.description" />,width: 250,dataIndex: 'descriptions',hideInSearch: true,hideInTable: true,render: (text) => (Array.isArray(text) ? text.join(', ') : text),},{title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="Operating" />,dataIndex: 'option',valueType: 'option',fixed: 'right',render: (_, record) => [<akey="update"onClick={() => {handleUpdateModalOpen(true);setCurrentRow(record);}}><FormattedMessage id="edit" defaultMessage="Edit" /></a>,access.canSuperAdmin && (<akey="delete"onClick={() => {return Modal.confirm({title: intl.formatMessage({ id: 'confirm.delete' }),onOk: async () => {await handleRemove([record._id!]);setSelectedRows([]);actionRef.current?.reloadAndRest?.();},content: intl.formatMessage({ id: 'confirm.delete.content' }),okText: intl.formatMessage({ id: 'confirm' }),cancelText: intl.formatMessage({ id: 'cancel' }),});}}><FormattedMessage id="delete" defaultMessage="Delete" /></a>),<akey="configure"onClick={() => {setConfigureModalVisible(true);setCurrentRow(record);}}>{intl.formatMessage({id: 'configure',defaultMessage: 'Configure',})}</a>,],},];return (<PageContainer><ProTable<API.ItemData, API.PageParams>headerTitle={intl.formatMessage({ id: 'list' })}actionRef={actionRef}rowKey="_id"scroll={{ x: 1200 }}search={{labelWidth: 120,collapsed: false,}}toolBarRender={() => [<Buttontype="primary"key="primary"onClick={() => {handleModalOpen(true);}}><PlusOutlined /> <FormattedMessage id="pages.searchTable.new" defaultMessage="New" /></Button>,selectedRowsState?.length > 0 && access.canSuperAdmin && (<ButtondangeronClick={() => {return Modal.confirm({title: intl.formatMessage({ id: 'confirm.delete' }),onOk: async () => {await handleRemove(selectedRowsState?.map((item) => item._id!));setSelectedRows([]);actionRef.current?.reloadAndRest?.();},content: intl.formatMessage({ id: 'confirm.delete.content' }),okText: intl.formatMessage({ id: 'confirm' }),cancelText: intl.formatMessage({ id: 'cancel' }),});}}><FormattedMessageid="pages.searchTable.batchDeletion"defaultMessage="Batch deletion"/></Button>),]}toolbar={{menu: {type: 'tab',activeKey: activeKey,items: [{label: <FormattedMessage id="platform.all" defaultMessage="All" />,key: '',},{label: <FormattedMessage id="platform.online" defaultMessage="Online" />,key: 'true',},{label: <FormattedMessage id="platform.offline" defaultMessage="Offline" />,key: 'false',},],onChange: (key: any) => {setActiveKey(key);if (actionRef.current) {actionRef.current.reload();}},},}}request={async (params, sort, filter) =>queryList('/platforms', { ...params, isOnline: activeKey }, sort, filter)}columns={columns}rowSelection={{onChange: (_, selectedRows) => {setSelectedRows(selectedRows);},}}/>{selectedRowsState?.length > 0 && (<FooterToolbarextra={<div><FormattedMessage id="pages.searchTable.chosen" defaultMessage="Chosen" />{' '}<a style={{ fontWeight: 600 }}>{selectedRowsState.length}</a>{' '}<FormattedMessage id="pages_searchTable_item" defaultMessage="items" /></div>}></FooterToolbar>)}<Createopen={createModalOpen}onOpenChange={handleModalOpen}onFinish={async (value) => {const success = await handleAdd(value as API.ItemData);if (success) {handleModalOpen(false);if (actionRef.current) {actionRef.current.reload();}}}}/><UpdateonSubmit={async (value) => {const success = await handleUpdate(value);if (success) {handleUpdateModalOpen(false);setCurrentRow(undefined);if (actionRef.current) {actionRef.current.reload();}}}}onCancel={handleUpdateModalOpen}updateModalOpen={updateModalOpen}values={currentRow || {}}/><ConfigureFormonSubmit={async (value) => {const success = await handleUpdate(value);if (success) {setConfigureModalVisible(false);setCurrentRow(undefined);if (actionRef.current) {actionRef.current.reload();}}}}onCancel={setConfigureModalVisible}updateModalOpen={configureModalVisible}values={currentRow || {}}/><Showopen={showDetail}currentRow={currentRow as API.ItemData}columns={columns as ProDescriptionsItemProps<API.ItemData>[]}onClose={() => {setCurrentRow(undefined);setShowDetail(false);}}/></PageContainer>);
};export default TableList;
主要是上面的 menu 的选项处理,还有
const [activeKey, setActiveKey] = useState<string | undefined>(‘’);
然后是请求列表里比较重要,
要把 activeKey 传给后端
request={async (params, sort, filter) =>queryList('/platforms', { ...params, isOnline: activeKey }, sort, filter)}
后端的参数是叫 isOnline ,要对上 key 和 value
其它的都没啥的问题。
我们拥有 12 年建站编程经验
- 虚拟产品交易平台定制开发
- WordPress 外贸电商独立站建站
我的网站