目录
- 官网
- 在项目中使用
- 下载
- 引入
- 方法1:全部引入
- 方法2:按需引入-手动加载
- 方法3:按需引入-自动加载
- 组件
- Anchor
- 作用:用于跳转到页面指定位置
- 案例1-基础使用
- 案例2-添加偏移量
- 案例3-指定容器
- 总结
- Modal
- error-弹框不显示(版本问题)
- Table
- 分页
- 表格添加多选框
官网
在项目中使用
下载
- 使用如下命令安装最新版本 - 5.1.4
npm i antd
- 目前使用的- 4.19.0
npm i antd@4.19
引入
方法1:全部引入
- [1]在App.css中引入样式
@import '~antd/dist/antd.css';
- [2] 在需要使用antd组件的 组件中引入组件并使用
import { Button } from 'antd';
export default function About (props) {
return (
<div>
我是about组件111<Button type="primary">Button</Button>
</div>
)
}
- 在页面显示如下
方法2:按需引入-手动加载
向方法1中及时只是使用Button组件,也需要将所有组件的样式引入。
为了提高性能,我们可以仅将自己需要的组件引入 -> 按需引入。
import Button from 'antd/lib/button';
import 'antd/lib/button/style';
export default function About (props) {
return (
<div>
我是about组件111<Button type="primary">Button</Button>
</div>
)
}
- 上述代码在页面显示如下
- 样式并没有起作用!
- 原因: ant design 在js中引入不起作用
@import 'antd/lib/button/style';
import Button from 'antd/lib/button';
import './index.css';
export default function About (props) {
return (
<div>
我是about组件111<Button type="primary">Button</Button>
</div>
)
}
上述代码能正确显示样式
方法3:按需引入-自动加载
使用方法2虽然可以实现按需加载,但是若是使用多个组件,还需要多次引入组件+样式
babel-plugin-import
插件可以帮助我们自动加载
- [1] 安装babel-plugin-import插件
npm i babel-plugin-import --save-dev
- [2] react配置文件默认是隐藏的 -> 使用命令
npm run eject
显示配置文件 - 在package.json 或 babel配置文件中添加配置
"babel": {
"presets": [
"react-app"
],
"plugins":[
["import", {
"libraryName":"antd",
"style":"css"
}]
]
}
重启项目
- [3]在组件中使用
import { Button } from 'antd';
function App() {
return (
<div className="App">
<Button type='primary'>1111</Button>
</div>
);
}
export default App;
在组件中通过如下方式引入
import { Button } from 'antd';
babel-plugin-import 插件会将上述代码转换为按需引入
import Button from 'antd/lib/button';
import 'antd/lib/button/style';
组件
Anchor
作用:用于跳转到页面指定位置
案例1-基础使用
将官方案例复制,稍作修改
import { Anchor } from 'antd';
import './useAnchor.css'
const { Link } = Anchor;
export default function UseAnchor(){
return(
<>
<div style={{ height: '100px', background: 'rgba(255,0,0,0.02)', marginBottom:'20px'}}></div>
<Anchor className='anchorlink'>
<Link href='#part-1' title='看点1' />
<Link href='#part-2' title='看点2' />
<Link href='#part-3' title='看点3' />
<Link href='#part-4' title='看点4' />
</Anchor>
<div id="part-1">
<h2>看点1</h2>
<div style={{ height: '200px', background: 'rgba(255,0,0,0.02)'}}></div>
</div>
<div id="part-2">
<h2>看点2</h2>
<div style={{ height: '200px', background: 'rgba(0,255,0,0.02)'}}></div>
</div>
<div id="part-3">
<h2>看点3</h2>
<div style={{ height: '200px', background: 'rgba(0,0,255,0.02)'}}></div>
</div>
<div id="part-4">
<h2>看点4</h2>
<div style={{ height: '200px', background: 'rgba(0,0,200,0.02)'}}></div>
</div>
</>
)
}
上述代码在页面显示如下:
可以看到 固定定位的元素遮盖了最前面的内容,我们可以设置一些偏移量
。
案例2-添加偏移量
在案例1的基础上进行更改 -> Anchor组件添加targetOffset属性
<Anchor className='anchorlink' targetOffset={40}>
但是有时候我们并不是在window元素进行锚点定位而是在某个元素内,就可以给Anchor组件指定一个容器。
案例3-指定容器
注意: 指定容器必须设置高度
和overflow:auto
;
在案例1的基础上进行修改
import { Anchor } from 'antd';
import './useAnchor.css'
const { Link } = Anchor;
export default function UseAnchor(){
return(
<>
<div style={{ height: '100px', background: 'rgba(255,0,0,0.02)', marginBottom:'20px'}}></div>
<div id='contain' style={{height:'300px', overflow: 'auto'}}>
<Anchor
className='anchorlink'
targetOffset={40}
getContainer={() => document.getElementById('contain')}
>
<Link href='#part-1' title='看点1' />
<Link href='#part-2' title='看点2' />
<Link href='#part-3' title='看点3' />
<Link href='#part-4' title='看点4' />
</Anchor>
<div id="part-1">
<h2>看点1</h2>
<div style={{ height: '200px', background: 'rgba(255,0,0,0.02)'}}></div>
</div>
<div id="part-2">
<h2>看点2</h2>
<div style={{ height: '200px', background: 'rgba(0,255,0,0.02)'}}></div>
</div>
<div id="part-3">
<h2>看点3</h2>
<div style={{ height: '200px', background: 'rgba(0,0,255,0.02)'}}></div>
</div>
<div id="part-4">
<h2>看点4</h2>
<div style={{ height: '200px', background: 'rgba(0,0,200,0.02)'}}></div>
</div>
</div>
</>
)
}
总结
- Anchor组件 用于包裹Link组件
- affix 是否固定为固定模式, 默认为固定模式
- 若是固定模式(true) :Anchor组件在滑动到当前组件之前是静态定位,滑动到当前组件之后为固定定位(固定在可视窗口的最顶端)
- 若是非固定模式(false):Anchor组件一直都为静态定位(不脱标)
- 举例说明 -> 案例1
- targetOffset:锚点滚动偏移量,默认为0
- 若是设置偏移量:对应元素不是滑动到当前元素的最顶端而是
最顶端下移对应偏移量
- 举例说明-> 案例2
- getContainer:指定滚动的容器,默认为
window
- 注意: 指定容器必须设置
高度
和overflow:auto
; - 举例说明 -> 案例3
- onClick事件
- 在这里可以阻止a标签的默认事件
- 若是滚动位置存在偏差,可在此进行设置
onClick={ (e, link)=>{
e.preventDefault()
// 找到锚点对应得的节点
let element = document.querySelector(link.href)
// 如果对应id的锚点存在,就跳滚动到锚点顶部
element && element.scrollIntoView({ block: 'end', behavior: 'smooth', alignToTop: 'false' })
}}
- Link组件 -> 最终被渲染为a标签
- href:锚点链接
- target:该属性指定在何处显示链接的资源
- title:文本内容
Modal
error-弹框不显示(版本问题)
在官网复制基础案例如下
import { useState } from 'react';
import { Button, Modal } from 'antd';
export default function UseInput(){
const [isModalOpen, setIsModalOpen] = useState(false);
const showModal = () => {
setIsModalOpen(true);
};
const handleOk = () => {
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
return (
<>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal title="Basic Modal" open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</>
)
}
在页面显示如下
点击按钮却不显示弹框
原因
我复制的案例是最新版(5.x),而项目使用的是4.19版本,弹框是否显示在4.23版本之前使用的是visible而非open;
改正
<Modal title="Basic Modal" visible={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
</Modal>
总结
- Modal对话弹框
- open属性: 控制弹框是否显示 -> 在
4.23版本之前使用的是visible属性而非open
- destroyOnClose属性:关闭时销毁 Modal 里的子元素
Table
分页
知识点
Table组件默认分页,每页默认展示10条数据
若是想要不分页可以设置属性
pagination={false}
若是想要隐藏分页html可以设置属性
pagination={{ position: ['none'] }}
(此时还是分页的,只是不渲染分页dom而已)
error
- 之前逻辑: 使用表格展示数据,默认每次请求并展示10条数据,代码如下:
<Table
pagination={{ position: ['none'] }}
columns={columns}
dataSource={refundList}
rowKey={(record) => (record.app_name + record.id)}
/>
<Pagination
total={refundCount}
showTotal={total => `总共有 ${total} 条数据`}
current={tablePage}
showSizeChanger={false}
onChange={(page)=>{
setTablePage(page)
getList(page)
}}
/>
function getList(page) {
const params = {
page,
pageSize: 10
}
// 发送请求获取数据
}
- 但是现在希望每页码展示100条数据,于是我在Pagination组件添加属性defaultPageSize
defaultPageSize = {100}
function getList(page) {
const params = {
page,
pageSize: 100
}
// 发送请求获取数据
}
- 发现现在后端返回的确实是100条数据,但是表格还是只渲染了10条数据。
- 问题的原因:
于是我搜索了"关于antd table组件中,数据渲染条数跟后台传入数据不一致的问题" 有的说是因为若是Ant Desgin中的Table会根据rowKey值进行自动去重,但是实际我设置的rowKey值是唯一的,因此pass。
我尝试在Table组件中添加了pageSize属性,发现可以每次渲染100条(渲染正确)
pagination={{ position: ['none'],pageSize:100 }}
我又尝试不使用Pagination组件而是使用Table里面的pagination属性设置分页,设置的内容一致,没想到渲染的数据就正确了(不再是10条了)。设置内容如下:
<Table
pagination={{
total: refundCount,
showTotal: total => `总共有 ${total} 条数据`,
defaultPageSize: 100,
current: tablePage,
showSizeChanger: false,
onChange: (page)=>{
setTablePage(page)
getList(page)
}
}}
columns={columns}
dataSource={refundList}
rowKey={(record) => (record.app_name + record.id)}
/>
- 原因:
- [1] Table组件的pagination={{ position: [‘none’] }} 的作用是隐藏分页dom,并不是不分页;
- [2] 设置pagination={{ position: [‘none’] }} 后默认还是10条每页;
- [3] 并且Table组件的分页配置优先级高于Pagination组件
因此即使我们设置了Pagination组件的defaultPageSize属性也不起作用(因为Table组件中的pagination属性设置的defaultPageSize优先级更高!)
表格添加多选框
Table组件若是配置了rowSelection
属性表示组件存在单/多选框,并且有关单/多选的配置都配置在rowSelection配置项中
- 默认多选框,若是更改可以通过
type
属性更改 - selectedRowKeys: 指定选中项的 key 数组(后期可用于
清除勾选
)
tips: 只要是配置了->若是数组的项不是对应的rowkey,则会出现勾选选不中的现象!
可以不配置该属性-> 若是需要清除勾选必须设置该属性!
- onChange: 选中值改变事件
onChange: (newSelectedRowKeys, selectedRows) => {
// newSelectedRowKeys为rowkey字段值
// selectedRows为该行的数据
setSelectedRowKeys(newSelectedRowKeys)
}
- getCheckboxProps: 判断该行是否可选
getCheckboxProps: (item) => ({
disabled: item.status
})
- 清除勾选
- [1] 配置selectedRowKeys属性
- [2] 在清除时将selectedRowKeys值设置为空数组即可
const [selectedRowKeys, setSelectedRowKeys] = useState([])
const onSelectChange = (newSelectedRowKeys, selectedRows) => {
setSelectedRowKeys(newSelectedRowKeys)
}
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
getCheckboxProps: (record) => ({
disabled: record.status == -1 || record.status == -2
})
}
<Table
ref={tableDom}
rowKey={(item) => item.id+item.app_name}
bordered
scroll={{ x: 2000 }}
sticky
columns={columns}
dataSource={orderList}
rowSelection={rowSelection}
pagination={{
total: count,
showSizeChanger: false,
current: fromData.current.page,
showTotal: (total)=>{
return `总共有 ${total} 条数据`
},
onChange: (e) => {
fromData.current.page = e
getOrders()
}
}}
/>
<Button className='callchargesOrders-from-btn' type="primary" block
onClick={()=>{
setSelectedRowKeys([])
}}
>
清除
</Button>
error
我写了一个表格,目前可以正常渲染,如下
现在我希望在表格左侧添加一个多选框,但是我只要配置rowSelection属性就会报错,即使我只是配置了一个type还是设置的默认值
rowSelection={{type: 'checkbox'}}
错误如下:
我看到错误上是和key有关,因此做了一个大胆猜测,是不是和rowKey
属性有关,因为我的rowkey设置如下
// 因为表格所有字段都不唯一,而rowKey需要唯一值,因此设置了一个随机数
rowKey={() => Date.parse(new Date()) + Math.random() * 79}
想到这里我将rowKey作出了如下更改
// 两个字段拼接值是唯一的
rowKey={(item) => item.id+item.app_name}
此时就可以了正常渲染了
接着我继续配置:希望勾选的时候获取到勾选的列的值(后端需要的是id)
const [selectedRowKeys, setSelectedRowKeys] = useState([])
rowSelection={{
selectedRowKeys,
onChange: (newSelectedRowKeys, selectedRows) => {
// newSelectedRowKeys为rowkey字段值
// selectedRows为该行的数据
setSelectedRowKeys(newSelectedRowKeys)
}
}}
此时才知道为什么rowkey在有选择框时不能是随机数,因为onChange事件的第一个参数其实是我们设置的该行的rowKey字段的值。
进行如上配置之后我随机选择了一行,selectedRowKeys的值为[‘17appname’] (是id与appname拼接的字符串)-> 这不是我想要的结果
因为这里id不唯一,因此不能将rowkey改为id字段
此时有两个选择
- 选择1
onChange: (newSelectedRowKeys, selectedRows) => {
setSelectedRowKeys(newSelectedRowKeys)
}
// 只有数字是id
const ids = selectedRowKeys.map(item=> Number(parseInt(item)))
- 选择2
onChange: (newSelectedRowKeys, selectedRows) => {
setSelectedRowKeys(selectedRows)
}
const ids = selectedRowKeys.map(item=> item.id))
我将2个选择都试了一下, 发现选择1没有问题,选择2出现勾选不上
的问题
原因
红圈标注字段是表格选中值,每一项必须与rowkey字段相匹配,在选择2中赋值的是整行数据的一个对象,匹配不上,因此出现了勾选但是勾选不上的问题
这时我把selectedRowKeys在rowSelection配置项中删除掉了,这样选择之后就不会对比了,此时选择2也没有问题了
const [selectedRowKeys, setSelectedRowKeys] = useState([])
rowSelection={{
onChange: (newSelectedRowKeys, selectedRows) => {
// newSelectedRowKeys为rowkey字段值
// selectedRows为该行的数据
setSelectedRowKeys(newSelectedRowKeys)
}
}}