Ant Design使用

官网

Ant Design官网

在项目中使用

在react中使用Ant Design

下载
  • 使用如下命令安装最新版本 - 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)
    }
  }}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值