pro-components
pro-components copied to clipboard
🐛[BUG] ProTable 搜索按钮抖动
🐛 bug 描述
通过路由进入,或者刷新页面会显示感觉到重置 查询按钮抖动,变形!
📷 复现步骤
搜索表格过多的情况,很明显 https://user-images.githubusercontent.com/12706830/187642429-164cc3d2-6a52-44d9-9ec7-eb2d91a16676.mov
搜索过少的页面,也有闪动 https://user-images.githubusercontent.com/12706830/187643862-e3c936ea-61eb-4410-ad81-f4946b95b2a9.mov
🏞 期望结果
期望正常不抖动,我默认不增加导出按钮,它也会抖动。
💻 复现代码
我把整个页面代码,贴出来。
import { useRef, useState } from 'react';
import { Tag, Space, Button, Avatar, Badge, Form, Input, Select } from 'antd';
import PageContainer from '@/components/PageContainer';
import ProTable, { ActionType, ProColumns } from '@ant-design/pro-table';
import { TableListItem } from './types';
import { queryMemberList } from './service';
import {
formatDate,
getEdu,
getGender,
getMarriage,
getMonthlyIncome,
getOccupation,
sourceFormat,
} from '@/utils/tool';
import PopoverSliderForm from '@/components/PopoverSliderForm';
import {
eduLabel,
genderLabel,
loveStatus,
marriageLabel,
occupationsLabel,
} from '@/utils/constant';
import DrawerPanel from './DrawerPanel';
const MemberList = () => {
const actionRef = useRef<ActionType>();
const [visible, setVisible] = useState(false);
const showDrawer = () => {
setVisible(true);
};
const columns: ProColumns<TableListItem>[] = [
{
title: '关键词',
hideInTable: true,
colSize: 2,
renderFormItem: () => {
return (
<Form.Item label="" noStyle>
<Input.Group compact>
<Form.Item name={['keywords', 'type']} noStyle initialValue={0}>
<Select placeholder="请选择" style={{ width: '40%' }}>
<Select.Option value={0}>按呢称搜</Select.Option>
<Select.Option value={1}>按姓名搜</Select.Option>
<Select.Option value={2}>按手机号搜</Select.Option>
<Select.Option value={3}>按ID搜</Select.Option>
</Select>
</Form.Item>
<Form.Item name={['keywords', 'name']} noStyle>
<Input style={{ width: '60%' }} placeholder="请输入关键词" />
</Form.Item>
</Input.Group>
</Form.Item>
);
},
},
{
dataIndex: 'love_id',
title: '用户ID',
search: false,
align: 'center',
width: 100,
},
{
dataIndex: 'avatar',
title: '头像',
search: false,
align: 'center',
width: 60,
render: (_, row) => {
return (
<Avatar
shape="square"
size={48}
src={sourceFormat(row.avatar, { m: 1, w: 200, h: 200 })}
/>
);
},
},
{
title: '资料',
search: false,
align: 'center',
width: 330,
render: (_, row) => {
return (
<div className="text-left f-12">
<div className="text-left">
<div className="d-flex align-items-end">
<span className="f-w f-14 mr-10">{row.nickname}</span>
<div
className={row.gender === 1 ? 'col-nan' : row.gender === 2 ? 'col-hot-pink' : ''}
>
{getGender(row.gender)}
</div>
{row.marriage > 0 && <span className="ml-10">{getMarriage(row.marriage)}</span>}
</div>
<div className="col-6">
<Space>
{row.age > 0 && <span>{row.age}岁</span>}
{row.height > 0 && <span>{row.height}cm</span>}
{row.weight > 0 && <span>{row.weight}kg</span>}
{row.education > 0 && <span>{getEdu(row.education)}</span>}
{row.occupation > 0 && <span>{getOccupation(row.occupation)}</span>}
{row.monthly_income > 0 && <span>{getMonthlyIncome(row.monthly_income)}</span>}
</Space>
<br />
<Space>
<span>籍贯:重庆市 永川区</span>
<span>现居:重庆市 永川区</span>
</Space>
</div>
</div>
</div>
);
},
},
{
title: '微信/手机号',
dataIndex: 'mobile',
// hideInTable: true,
width: 130,
align: 'center',
search: false,
formItemProps: {
label: '手机号',
},
render: (val, row) => {
return (
<Space direction="vertical">
<span>{row.wechat ? row.wechat : '-'}</span>
<span>{val ? val : '-'}</span>
</Space>
);
},
},
{
title: '性别',
dataIndex: 'gender',
hideInTable: true,
valueType: 'select',
request: async () => genderLabel,
},
{
title: '实名',
dataIndex: 'auth_realname',
hideInTable: true,
valueType: 'select',
request: async () => [
{ label: '已实名', value: 1 },
{ label: '未实名', value: 0 },
],
},
{
title: '婚况',
dataIndex: 'marriage',
hideInTable: true,
valueType: 'select',
request: async () => marriageLabel,
// renderFormItem: ()=> {}
},
{
title: '学历',
dataIndex: 'education',
hideInTable: true,
valueType: 'select',
request: async () => eduLabel,
},
{
title: '职业',
dataIndex: 'job',
hideInTable: true,
valueType: 'select',
request: async () => occupationsLabel,
},
{
title: '收入',
dataIndex: 'salary',
hideInTable: true,
valueType: 'select',
request: async () => [
{ label: '未婚', value: 1 },
{ label: '离异', value: 2 },
{ label: '丧偶', value: 3 },
],
},
{
title: '年龄',
dataIndex: 'age',
hideInTable: true,
renderFormItem: () => {
return (
<PopoverSliderForm typeName="年龄" min={18} max={45} unit="岁" defaultVal={[20, 25]} />
);
},
},
{
title: '身高',
dataIndex: 'height',
hideInTable: true,
renderFormItem: () => {
return (
<PopoverSliderForm
typeName="身高"
min={150}
max={200}
unit="CM"
defaultVal={[158, 175]}
/>
);
},
},
{
title: '体重',
dataIndex: 'weight',
hideInTable: true,
renderFormItem: () => {
return (
<PopoverSliderForm typeName="体重" min={40} max={100} unit="KG" defaultVal={[45, 65]} />
);
},
},
{
title: '购房',
dataIndex: 'house',
hideInTable: true,
valueType: 'select',
request: async () => [
{ label: '已购房(居家)', value: 1 },
{ label: '已购房(多套)', value: 2 },
{ label: '暂未购房', value: 3 },
{ label: '随时可购置', value: 4 },
],
},
{
dataIndex: 'integral',
title: '积分',
search: false,
align: 'center',
},
{
title: '实名',
dataIndex: 'mobile',
// hideInTable: true,
width: 80,
align: 'center',
search: false,
render: () => {
return <Tag color="success">已实名</Tag>;
},
},
{
dataIndex: 'love_status',
title: '相亲状态',
width: 100,
align: 'center',
valueType: 'select',
request: async () => loveStatus,
render: (_, row) => {
switch (row.love_status as number) {
case 1:
return <Tag color="success">公开相亲</Tag>;
case 2:
return <Tag color="gold">委托红娘</Tag>;
case 3:
return <Tag color="magenta">已脱单</Tag>;
default:
return <Tag>关闭相亲</Tag>;
}
},
},
{
dataIndex: 'matchmaker',
title: '红娘',
align: 'center',
request: async () => [{ label: '番茄', value: 1 }],
width: 100,
valueType: 'select',
},
{
dataIndex: 'status',
title: '状态',
align: 'center',
formItemProps: {
label: '用户状态',
},
request: async () => [
{ label: '正常', value: 1 },
{ label: '审核中', value: 2 },
{ label: '异常用户', value: 3 },
{ label: '黑名单', value: 4 },
],
width: 100,
render: () => {
return <Tag color="success">正常</Tag>;
},
},
{
title: '注册时间',
dataIndex: 'create_time',
valueType: 'date',
width: 190,
align: 'center',
render: (_, record) => {
return (
<Space direction="vertical">
<div className="col-6">公众号</div>
<div>{formatDate(record.create_time)}</div>
</Space>
);
},
},
{
title: '操作',
width: 80,
search: false,
align: 'center',
render: () => {
return (
<Space className="mt-6">
<Badge count={2} style={{ display: 'none' }}>
<Button size="small" type="primary" ghost style={{ display: 'none' }}>
服务跟进
</Button>
</Badge>
<Badge count={2} style={{ display: 'none' }}>
<Button size="small" type="primary" ghost style={{ display: 'none' }}>
牵线记录
</Button>
</Badge>
<Button size="small" type="primary" onClick={showDrawer}>
详细资料
</Button>
</Space>
);
},
},
];
return (
<>
<PageContainer>
<ProTable<TableListItem>
headerTitle="用户列表"
actionRef={actionRef}
rowKey="id"
columns={columns}
rowSelection={{}}
search={{
labelWidth: 'auto',
span: 4,
collapsed: false,
collapseRender: false,
optionRender: (searchConfig, formProps, dom) => [
<Button key='out' onClick={() => {
//searchConfig?.form?.getFieldsValue()
}}>
导出
</Button>,
...dom
]
}}
// columnsState={}
request={async (params) => {
const res = await queryMemberList({ ...params });
return {
data: res.result.data,
success: true,
total: res.result.total,
};
}}
/>
</PageContainer>
<DrawerPanel visible={visible} />
</>
);
};
export default MemberList;
整个package.json
{
"name": "jilian",
"version": "5.2.0",
"private": true,
"description": "An out-of-box UI solution for enterprise applications",
"scripts": {
"analyze": "cross-env ANALYZE=1 umi build",
"build": "umi build",
"deploy": "npm run build && npm run gh-pages",
"dev": "npm run start:dev",
"gh-pages": "gh-pages -d dist",
"i18n-remove": "pro i18n-remove --locale=zh-CN --write",
"postinstall": "umi g tmp",
"lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier && npm run tsc",
"lint-staged": "lint-staged",
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style",
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
"lint:prettier": "prettier -c --write \"src/**/*\" --end-of-line auto",
"lint:style": "stylelint --fix \"src/**/*.less\" --syntax less",
"openapi": "umi openapi",
"playwright": "playwright install && playwright test",
"prepare": "husky install",
"prettier": "prettier -c --write \"src/**/*\"",
"serve": "umi-serve",
"start": "cross-env UMI_ENV=dev umi dev",
"start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev",
"start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev",
"start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev",
"start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev",
"start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev umi dev",
"test": "umi test",
"test:component": "umi test ./src/components",
"test:e2e": "node ./tests/run-tests.js",
"tsc": "tsc --noEmit"
},
"lint-staged": {
"**/*.less": "stylelint --syntax less",
"**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
"**/*.{js,jsx,tsx,ts,less,md,json}": [
"prettier --write"
]
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
],
"dependencies": {
"@ant-design/charts": "^1.4.2",
"@ant-design/icons": "^4.7.0",
"@ant-design/pro-components": "^1.1.21",
"@umijs/route-utils": "^2.0.0",
"antd": "^4.20.0",
"classnames": "^2.3.0",
"lodash": "^4.17.0",
"moment": "^2.29.0",
"omit.js": "^2.0.2",
"rc-menu": "^9.1.0",
"rc-util": "^5.16.0",
"react": "^17.0.0",
"react-dev-inspector": "^1.7.0",
"react-dom": "^17.0.0",
"react-helmet-async": "^1.2.0",
"umi": "^3.5.0"
},
"devDependencies": {
"@ant-design/pro-cli": "^2.1.0",
"@playwright/test": "^1.17.0",
"@types/classnames": "^2.3.1",
"@types/express": "^4.17.0",
"@types/history": "^4.7.0",
"@types/jest": "^26.0.0",
"@types/lodash": "^4.14.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-helmet": "^6.1.0",
"@umijs/fabric": "^2.11.1",
"@umijs/openapi": "^1.6.0",
"@umijs/plugin-blocks": "^2.2.0",
"@umijs/plugin-esbuild": "^1.4.0",
"@umijs/plugin-openapi": "^1.3.3",
"@umijs/preset-ant-design-pro": "^1.3.0",
"@umijs/preset-dumi": "^1.1.0",
"@umijs/preset-react": "^2.1.0",
"compression-webpack-plugin": "^10.0.0",
"cross-env": "^7.0.0",
"cross-port-killer": "^1.3.0",
"detect-installer": "^1.0.0",
"eslint": "^7.32.0",
"file-loader": "^6.2.0",
"gh-pages": "^3.2.0",
"husky": "^7.0.4",
"jsdom-global": "^3.0.0",
"lint-staged": "^10.0.0",
"mockjs": "^1.1.0",
"prettier": "^2.5.0",
"stylelint": "^13.0.0",
"swagger-ui-dist": "^4.12.0",
"typescript": "^4.5.0",
"umi-serve": "^1.9.10",
"url-loader": "^4.1.1"
},
"engines": {
"node": ">=12.0.0"
}
}
© 版本信息
- ProComponents 版本: [1.1.21]
- umi 版本: [3.5.32]
- 浏览器环境
- 开发环境 [e.g. mac OS]
以下的 Issues 可能会帮助到你 / The following issues may help you
- [#5348][ProTable][85%]
看了下是request loading数据的时候 button 组件上有loading撑起,导致抖动撑坏页面。希望给个参数让button变化的情况下不要变大或缩小。或者加载的时候直接用disabled把它禁用掉。禁止二次点击!
没有人关注嘛!@chenshuai2144
没人嘛!
按钮宽度边框导致的,你把查询按钮所占的格子弄得大一点
按钮宽度边框导致的,你把查询按钮所占的格子弄得大一点
具体怎么设置,感谢
这就关闭了?弄格子不现实,是你们loading撑坏的。可不可以手动控制loging样式不显示!