Antd v4踩坑记录

DatePicker渲染时间选择器初始值

dayjs转换时间,转换2023-4-2 00:00:00号,日期和时间需要加个空格隔开,否则转换为2023-4-20号
useMount(() => {
if (date) {
   // console.log('didid', date, date + '00:00:00', dayjs(date + ' 00:00:00'));
  form.setFieldsValue({ jhsj: [dayjs(date + ' 00:00:00'), dayjs(date + ' 23:59:59')] });
  setTimeout(() => {
  submit();
  }, 300);
} else {
  submit();
}
});

Form表单

调用form.setFieldsValue()时,不触发onValuesChange回调,解决办法

可以通过在调用form.setFieldsValue()时,手动触发onValuesChange回调来解决。具体实现如下:

先定义一个变量isSettingFieldsValue,用于标记当前是否正在调用form.setFieldsValue()方法。然后在调用setFieldsValue()方法之前,将该变量设置为true,在回调函数中判断该变量是否为true,如果是则手动触发onValuesChange回调;否则,直接返回。

示例代码如下:

let isSettingFieldsValue = false;
const handleChange = (changedValues) => {
 if(isSettingFieldsValue) {
   const { onValuesChange } = this.props;
   onValuesChange && onValuesChange(changedValues, form.getFieldsValue());
}
}
const handleSetFieldsValue = (fieldsValue) => {
 isSettingFieldsValue = true;
 form.setFieldsValue(fieldsValue);
 isSettingFieldsValue = false;
}
// 使用方法
handleSetFieldsValue({name: 'foo', age: 18});

在handleChange回调函数中,我们先判断isSettingFieldsValue是否为true,如果是,则手动调用onValuesChange回调函数,并将changedValues和当前表单所有值的对象传入;否则,直接返回,不做任何处理。

在handleSetFieldsValue函数中,我们首先将isSettingFieldsValue设置为true,表示当前正在调用setFieldsValue方法;然后通过调用form.setFieldsValue(fieldsValue)方法来更新表单值;最后将isSettingFieldsValue设置为false,表示setFieldsValue方法已经执行完毕。

这样,在调用setFieldsValue方法时,不仅可以更新表单的值,同时也能手动触发onValuesChange回调函数。

form表单自定义校验

在自定义校验中添加必填的验证,可以在验证规则中使用required,并将它与自定义校验函数结合使用。以下是修改后的示例代码:
import React, { useState } from "react";
import { Form, Select, Input } from "antd"; 
const { Item } = Form; const MyForm = () => { const [inputValue, setInputValue] = useState(""); 
const [parameterType, setParameterType] = useState(""); 
// 自定义校验规则 
const validateParameterValue = (rule, value, callback) => { 
if (!value) { callback("参数值不能为空"); } 
else if (!/^[\u0020-\u007E\u4E00-\u9FA5]*$/.test(value))
{ callback("参数值只能包含键盘上可见的字符、汉字"); }
else { callback(); } }; 
const handleParameterChange = (value) => { setParameterType(value); };
const handleInputChange = (event) => { setInputValue(event.target.value); };
return ( 
<Form> 
<Item label="参数名称" name="parameterName">
 <Select onChange={handleParameterChange}>
 <Select.Option value="文本">文本</Select.Option> 
<Select.Option value="数字">数字</Select.Option> 
<Select.Option value="日期">日期</Select.Option>
 </Select> 
</Item> 
<Item label="参数值" name="parameterValue" rules={[ { required: true, message: "参数值不能为空" }, { validator: validateParameterValue } ]} > 
 <Input value={inputValue} onChange={handleInputChange} /> 
</Item> 
</Form> ); };
export default MyForm; 
在上述代码中,我们首先添加了{ required: true, message: "参数值不能为空" }这个验证规则,用于确保参数值不为空。然后,在自定义校验函数中,我们通过判断参数值是否为空来返回相应的错误信息。

这样,用户在提交表单时,如果参数值为空或者包含非键盘上可见的字符,都会显示相应的错误提示。同时也满足了参数值必填的要求。

Modal模态框

v4:visible={visible}   v5: open={visible}

open对话框是否可见,小于 4.23.0 用visible

重新加载模态框内容不刷新:

destroyOnClose={true}

destroyOnClose关闭时销毁 Modal 里的子元素

select下拉框下拉触底分页滚动加载选项

import { Select } from 'antd';
import React, { useEffect, useState } from 'react';
import { cloneDeep, get } from 'lodash-es';
import {  useDebounceFn } from 'ahooks'
import { useMount } from 'ahooks';
const ScrollSelect: React.FC = (props) => {
  const {onChange}=props
  const [selectArr, setSelectArr] = useState([]); //下拉框数组
  const [loading, setLoading] = useState(false); //加载loading
  const PAGE_SIZE = 2; //每页数量
  const [page, setPage] = useState(1); //当前页,默认第一页开始
  const [scrollPageTotal, setScrollPageTotal] = useState<number>(0);
  const [hasMore, setHasMore] = useState(true); //是否还有更多数据需要加载
  const [keyword, setKeyword] = useState<string>('');
  //数据处理/下一页/是否继续请求
  const getSelectArr = async (ids:ISafeAny) => {
    if (!hasMore) {
      return;
    }
    setLoading(true);
    try {
      const res = await postData({ page: page, page_size: PAGE_SIZE,ids, keyword:keyword }) //api请求
      console.log('res.data.data.results', res.data.data.results);
      if (res.data.code !== -1) {
        setSelectArr((prevData) => [...prevData, ...res.data.data.results]); // 更新数据(eg:第二页和第一页合并数组,第三页和前两页合并...)
        setPage(page + 1); //更新为下一个(eg:第一页变成请求第二页,再第三页..,以此类推...)
        setScrollPageTotal(get(res, 'data.data.total'));
        setHasMore(res.data.data.results.length === PAGE_SIZE);
      }
      setLoading(false);
    } catch (err) {
      console.error(err);
    }
  };



  //滚动时操作函数
  const handleScroll = (event) => {
    const { target } = event;
    if (!loading && target.scrollTop + target.offsetHeight === target.scrollHeight) {
      setLoading(true);
      const nextScrollPage = cloneDeep(page) + 1;
      setPage(nextScrollPage);
      nextScrollPage <= scrollPageTotal && getSelectArr(null);
    }
  };
// 搜索回调
const { run: handleSearch } = useDebounceFn(
  async (newValue: string) => {
    // 重置参数,重新请求
    setKeyword(newValue)
    setPage(1)
    getSelectArr(null);
  },
  { wait: 500 },
);
  useEffect(() => {
    getSelectArr(props.value);
  }, [props.value]);

  return (
    <Select
      mode="multiple"
      showSearch
      placeholder="请选择"
      optionFilterProp="children"
      onChange={onChange}
      onSearch={(value: string) =>  {console.log(`Search ${value}`),handleSearch(value)}}
      filterOption={(input, option) =>
        (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
      }
      value={props.value}
      options={
        Array.isArray(selectArr) &&
        selectArr?.map((item) => {
          return {
            key: item.ry_id,
            label: item.ryxm,
            value: item.ry_id,
          };
        })
      }
      virtual={false}
      onPopupScroll={(e) => handleScroll(e)}
      getPopupContainer={(triggerNode) => triggerNode.parentNode}
      listHeight={100}
    />

  );
};

export default ScrollSelect;

TreeSelect 树选择器

1.TreeSelect树选择器的搜索

<TreeSelect
  treeData={treeData}   // 后端返回的json数据,渲染页面
  placeholder="请输入"
  onChange={() => this.onChange}
  showSearch//仅支持单选模式
  treeNodeFilterProp="title"  // 官网解释说,输入项过滤对应的 treeNode 属性,默认是’value‘,而我们的value可能是number,搜索就会出错;我们设置成title,搜索就改成了我们的文字搜索。
  showCheckedStrategy={SHOW_ALL}//选中显示所有父+子拼接全名
  treeNodeLabelProp='allName'
/>

默认属性解决办法就是treeNodeFilterProp切换title和value过滤搜索。扩展treeNodeLabelProp属性,作为显示的 prop 设置,默认是title,选中下拉选项,展示title,或者value。

2.treeselect选中后回显的数据是选中的title,返回的数据是key

用的 fieldNames属性:fieldNames={{ label: 'slot_path_name', value: 'slot_id', children: 'children' }}

DatePicker

自定义日期选择器当天样式

import { DatePicker } from 'antd';

import React from 'react';

const CustomDatePicker = () => { const dateCellRender = (current) => {

const isToday = current.isSame(new Date(), 'day'); // 判断是否为当天日期

return ( <div className={`ant-picker-cell-inner ${isToday ? 'today' : ''}`}> {current.date()} </div> ); };

return ( <DatePicker dateRender={dateCellRender} /> ); };

export default CustomDatePicker;

也可以直接修改样式css:

.ant-picker-cell-today{
  color:#2ec37b;
}
.ant-picker-cell-today .ant-picker-cell-inner::before{
  border: none!important;
}

AutoComplete 自动完成

可以用来传options=[]实现又是下拉选择框又是输入框的效果。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值