antd 使用踩坑

29 篇文章 1 订阅

antd Tree组件使用expandedKey之后无法展开和收起节点怎么办?

答:要配合onExpand事件一起使用鸭,与Checkbox 有异曲同工之妙。

// dom
 <Tree showIcon={true} defaultExpandAll defaultExpandParent 
	   autoExpandParent
	   selectedKeys={[this.state.activeMenuCode]}
	   expandedKeys={this.state.treeExpandedKeys}
	   onExpand={this.onExpand}
   >{renderEntityTreeNodes(this.state.menuTreeData)}</Tree>
   // js
   onExpand = expandedKeys => {
        this.setState({
		  treeExpandedKeys: expandedKeys
        });
	} 

antd Select defaultValue 不动态改变,如何动态设置 ?

加个key值:获取到数据之前,组件已经 render了

<Select
                key = {val}
                defaultValue={val}
                style={{ width: 200 }}
                onChange={handleCurrencyChange}
                >
                    {
                        list.length > 0 && list.map(e => {
                            return (
                                <Option value={e}>{e}</Option>
                            )
                        })
                    }
                </Select>

Warning: defaultValue is invalid for getFieldDecorator will set value,

原因:用getFieldDecorator包裹,所以使用defaultValue会报错,需要使用initialValue代替,并且这个属性需要放在getFieldDecorator种作为参数,不能放在Input或者其它组件中

defaultSelectedKeys和selectedKeys

antd Tree组件,默认选中树,为变量时,使用defaultSelectedKeys不会重新渲染,只使用第一个获得的值,可能导致条件判断失效,此时使用selectedKeys,但要注意:selectedKeys要和onSelect事件配合使用。更好的是在函数组件中使用,更简洁。
最好还是使用selectedKeys,更稳定,问题定位更清晰。

value和defaultValue

问题还原:使用Table组件,做增删改查的操作,table内含有Select和DatePicker组件,当做删除时,每次删除的都是最后一个值。
问题解决:因为使用了onChange事件,对应的defaultValue应该改为value,即可避免此问题

antd select,滚动页面时内容与输入框分离

解决:
在Select组件中添加 getPopupContainer={triggerNode => triggerNode.parentNode}

Ant design tree defaultExpandAll={true} 不生效

如果数据源是同步数据,则可以直接生效,如果是异步请求得数据,则需要等获取到数据之后才渲染Tree。

{
                                this.state.menuTreeData.length > 0  && <Tree showIcon={true} autoExpandParent={true} defaultExpandAll={true} defaultExpandParent={true}
                                selectedKeys={[this.state.activeMenuCode]}
                                onSelect={this.handleTreeSelect}
                                >{renderEntityTreeNodes(this.state.menuTreeData)}</Tree>
                            }

antd Table表头可拉伸,拉伸时触发排序

通过 resizing 控制是否可点击排序

const components = {
  header: {
    cell: props => {
      const { onResize, width, onClick, ...restProps } = props;
      let resizing = false;
      if (!width) {
        return <th {...restProps} />;
      }
      return (
        <Resizable
          width={width}
          height={0}
          onResize={onResize}
          draggableOpts={{ enableUserSelectHack: false }}
          onResizeStart={() => {
            resizing = true;
   
        }}
   
        onResizeStop={() => {
          resizing = true;
          setTimeout(() => {
            resizing = false;
          },100);
   
        }}
        >
          <th {...restProps} onClick={(...args) => {
            if (!resizing) {
              onClick(...args);
             }
            }} />
        </Resizable>
      );
    },
  },
}

table多选 不同页面选择互相影响

在使用rowSelection属性的同时,加上rowKey就可以解除影响

rowSelection={rowSelection}
            rowKey={record => record.id}

使用getFieldDecorator之前,必须先使用 Form.create({ })(Form) 将表单组件包裹起来

ref 使用 wrappedComponentRef={ref => this.$BaseEditForm = ref}

model每次打开时候莫名会闪动一下

原因:还没想通,有时间再想(任务调度)
解决方式:把打开得方法变成异步,最简单得方法,加个定时器

Form Input框想既能输入内容,又能选择填充内容。但是当输入内容后,填充内容时,无法对input框内的内容进行改变

在这里插入图片描述

先清空input框中的内容
 genenrateKey = () => {
        this.props.form.resetFields(`userPswd`,'');
        this.props.genenrateKey();
     }
设置要填充的内容
// 生成密匙
     genenrateKey = async () => {
        let res = await this.serviceTest();
        if (res.code !== '200') return message.error(res.message);
        this.setState({genenrate_key: res.data})
     }
填充
<FormValidItem label="密钥" 
                             {getFieldDecorator("userPswd", {
                                 initialValue: menuEditData.userPswd || genenrate_key
                             })(
                                <Input allowClear style={{ width: 502}} placeholder="密钥" addonAfter={ButKey} />
                             )}
                    </FormValidItem> 

antd form ref

antd form 有增删改查的时候,要注意value 和onchange配合使用,只有defaultValue会让页面展示效果出现异常。
form ref的使用
1, wrappedComponentRef={(form) => this.$expand = form}
2,
3, Form.create()(forwardRef(SlotTemplate))

table 的 selectedRowKeys 拿到的是table中的key值,所以处理数据的时候最好遍历给每个数据加个key值

Form 表单如果需要拆分为不同的子组件时

子组件不要重新用 包裹,直接用<></>更方便,因为最明显的坑是如果用FORM包裹,那么提交时如果不做子组件的校验判断,则不会校验子组件的必填项。
当然,如果你已经这样做了,想要校验子组件,只需要将validateFields暴漏出去,然后

this.props.form.validateFields((err) => {//***
          if (err) {
             // 校验不通过  
             return;
          }else{
            // TODO 校验通过     
          }
 }})

使用less 不生效

1、引入 less-loader,less
2、webpack.config.js 配置

{
			        test: /\.less$/,
			        use: [{
			          loader: "style-loader" // creates style nodes from JS strings
			        }, {
			          loader: "css-loader" // translates CSS into CommonJS
			        }, {
			          loader: "less-loader" // compiles Less to CSS
			        }]
			      },

antd 报错 Warning: [antd: Icon] Should have type prop or component prop or children.

这样的报错可能是你没有传type值或者,给传type传了null或者Undefined.
但其实发现传一个空字符串也是会报错的=》‘’。那么如果不想传值用什么呢,用’ ',就可以,差别在于打了一个空格

select 搜索和远程数据结合时,数据过多,导致页面卡死怎么办?

我这里得前提是我得接口是分页接口。
其余跟官方文档使用相同,只不过加一个onPupopScroll函数,也就是滚动回调函数.
当滚动到底层时,则请求下一页,把下一页得数据与当前页拼接到一起即可。很简单得实现方法,但是挺好用的。

// 滚动
       onPopupScroll = e => {
        e.persist();
        const { target } = e;
        let {num, search, data} = this.state;
        const rmHeight = target.scrollHeight - target.scrollTop;
        const clHeight = target.clientHeight;
        // 滑倒底
        if (rmHeight == clHeight) {
            num ++;
            getSecuritiesCode({val: search, num})
            .then(d => {
                if (currentValue === search) {
                    const new_data = [];
                    const obj = {}; //下拉框键值对
                    d.data.list.forEach(r => {
                        new_data.push({
                        value: r.securitiesCode,
                        text: r.securitiesName,
                        });
                        obj[r.securitiesCode] = r.securitiesName;
                    });
                    this.setState({
                        data: [...data, ...new_data],
                        num
                    })
                }
            })
        }
      }

antd form 禁用所有控件

let { getFieldDecorator } = props.form;
    const { tableType, info, menuEditData } = props;
    if(info) {
        getFieldDecorator = (...rest) => {
            return element => {
                let NewElement = React.cloneElement(element, {
                    disabled: true
                });
                return props.form.getFieldDecorator(...rest)(NewElement);
            };
        };
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ant Design 是一个 UI 框架,而 PDF.js 是 Mozilla 开发的一款开源的 JavaScript PDF 阅读器。您可以使用 Ant Design 的 Upload 组件上传 PDF 文件,在上传完成后,通过 PDF.js 渲染出 PDF 文件的预览效果。具体实现方式可以参考以下步骤: 1. 在上传组件中,通过 `beforeUpload` 属性来获取上传文件的 Blob 数据,并将其传入 PDF.js 进行渲染。 ```jsx import React, { useState } from 'react'; import { Upload } from 'antd'; import pdfjs from 'pdfjs-dist/webpack'; const { Dragger } = Upload; const PdfPreview = () => { const [pdfUrl, setPdfUrl] = useState(null); const handleBeforeUpload = (file) => { const reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = async (event) => { const pdfData = new Uint8Array(event.target.result); const loadingTask = pdfjs.getDocument({ data: pdfData }); const pdf = await loadingTask.promise; const page = await pdf.getPage(1); const scale = 1.5; const viewport = page.getViewport({ scale }); const canvas = document.createElement('canvas'); const canvasContext = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; const renderContext = { canvasContext, viewport, }; const renderTask = page.render(renderContext); await renderTask.promise; setPdfUrl(canvas.toDataURL()); }; return false; }; return ( <Dragger beforeUpload={handleBeforeUpload}> <p className="ant-upload-drag-icon"> <InboxOutlined /> </p> <p className="ant-upload-text">点击或拖拽文件到此处上传</p> </Dragger> {pdfUrl && <img src={pdfUrl} alt="PDF preview" />} ); }; export default PdfPreview; ``` 在上述代码中,我们使用了 `pdfjs-dist/webpack` 模块来加载 PDF.js 库,然后在 `beforeUpload` 属性中获取上传文件的 Blob 数据,通过 PDF.js 进行渲染,并将渲染后的图片数据作为 URL 存储在组件的状态中,最后将图片渲染在页面上。 2. 在渲染 PDF 预览时,可以使用 Ant Design 的 Image 组件来显示图片。 ```jsx import React, { useState } from 'react'; import { Upload, Image } from 'antd'; import pdfjs from 'pdfjs-dist/webpack'; const { Dragger } = Upload; const PdfPreview = () => { const [pdfUrl, setPdfUrl] = useState(null); const handleBeforeUpload = (file) => { const reader = new FileReader(); reader.readAsArrayBuffer(file); reader.onload = async (event) => { const pdfData = new Uint8Array(event.target.result); const loadingTask = pdfjs.getDocument({ data: pdfData }); const pdf = await loadingTask.promise; const page = await pdf.getPage(1); const scale = 1.5; const viewport = page.getViewport({ scale }); const canvas = document.createElement('canvas'); const canvasContext = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; const renderContext = { canvasContext, viewport, }; const renderTask = page.render(renderContext); await renderTask.promise; setPdfUrl(canvas.toDataURL()); }; return false; }; return ( <Dragger beforeUpload={handleBeforeUpload}> <p className="ant-upload-drag-icon"> <InboxOutlined /> </p> <p className="ant-upload-text">点击或拖拽文件到此处上传</p> </Dragger> {pdfUrl && <Image src={pdfUrl} />} ); }; export default PdfPreview; ``` 在上述代码中,我们使用了 Ant Design 的 Image 组件来显示 PDF 预览图片。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值