最近一两个月的时间在开发公司的后台管理系统.用的是技术栈是Antd+Dva+Umi,记得在之前也用过一次,做过一个后台,但是时间久啦.然后Antd的版本也更新到V4啦.很多组件的API用法也发生了相应的变化.做一个简单的归纳总结和记录,可能写的比较零碎,想到什么就记录什么,比较随意......

一个页面多个弹框展示效果:

一般的后台管理系统,右侧顶部有相关的搜索框,字段比较多的可能会设计为展开效果.下面一般为一个Table列表数据.对于列表table数据,会有一些相关的操作弹框展示.对于一个页面多个弹框的效果.建议设置一个对象Object来存储对应的显示影藏状态.

例如: 现在基本都是用Hooks进行开发 (开始的时候设置初始值均为false)

const [showDialog, setShowDialog] = useState({
    adduserShow: false,
    authShow: false,
    deleteShow: false,
    resetShow: false,
});

显示页面弹框: (设置对应的弹框属性为true)

const showModal = ( type, record) => {
    const data = { ...showDialog };
    data[type] = true;
    setRecord(record);
    setShowDialog(data);
};

影藏页面弹框: (设置对应的弹框属性为false)

  const hideModal = (type) => {
    const data = { ...showDialog };
    data[type] = false;
    setShowDialog(data);
  };

点击对应的操作时候,传入对应的type即可.onClick={() => showModal('addroleShow', record)}

编辑和新增共用同一个弹框,编辑的时候,传入record记录,新增的时候传入一个空对象{}即可,对于这种同步的弹框显示影藏,建议直接放在state中就可以啦.当然,你也可以放到
Model里的state进行定义,然后模板dispatch一个action来改变.

表单赋初始值和弹框中的表单(子组件)请求异步接口数据

表单赋初始值

// 默认初始值的时候,set一个初始值存入 ,新增的时候,默认初始值,要这种写法才生效
// 有时候列表返回的数据与表单中自己定义的name值不对应,我们可以拿到列表数据进行一次map循环然后合并.
// 编辑和新增操作.可以通过props传入的值进行判断,合理使用影藏域(type="hidden")类型

useEffect(() => {

    const channel = getItem('productShunt', '0');

    props.dispatch({ type: 'INSURESHUNTADD/detail', payload: channel }).then((res) => {

      const proList = res.productShuntList && res.productShuntList.map((item, index) => {
        const {
          insurerCode,
          versionName
        } = res.productShuntList[index];
        return {
          ...item,
          sight: insurerCode,
          pro: versionName
        };
      });
      const defaultValues = {
        "channelName": res.channelName ? [`${res.channelName}`] : undefined,
        "channelSource": res.channelSource ? [`${res.channelSource}`] : undefined,
        "available": res.channelName ? res.productShuntList[0].available : available,
        "productShuntDetailVOS": proList, // 配置表单list重新赋值
        "channelList": res.productShuntList && ([].concat(`${res.productShuntList[0].channelCode}#${res.productShuntList[0].channelSource}`)),
        "effectiveTime": res.productShuntList && (moment(res.productShuntList[0].effectiveTime, 'YYYY-MM-DD HH:mm:ss'))
      }

      form.setFieldsValue(res.channelName ? defaultValues : { productShuntDetailVOS: [{}] });

    })


  }, [form]);

页面效果

编辑该条信息表单默认赋值:

页面效果

Antd版本升级到V4 后,对于动态表单新增每一项,提供了一个Form.List的API使用.

弹框中子组件展示默认数据(请求异步接口)

子组件里面的数据和方法通过props传递过去,子组件触发父组件的方法.

在父组件中,是否展示子组件要进行判断,页面初始化的时候就会渲染子组件,从而导致拿不到值,传递的数据子组件中为undefined.

编辑操作的时候,可以不用是因为编辑操作的时候,可以传入record拿到对应的值,非异步


<UserinfoForm {...addUserform}></UserinfoForm>
{ showDialog.authShow && <AuthForm {...authUserform}></AuthForm>}

页面效果

Datepicker组件赋初始值和分页组件汉化以及搜索功能相关问题

  • RangePicker组件赋值时候需要为moment对象.例如:到今天三个月前时间
initialValue={
[moment(moment().subtract(3, "months"), "YYYY-MM-DD"), moment(new Date(), "YYYY-MM-DD")]
}
  • Datepicker以及pagination组件汉化问题

//引入文件 import locale from 'antd/lib/date-picker/locale/zh_CN';
//引入文件 import moment from 'moment';
//引入文件 import 'moment/locale/zh-cn';

<DatePicker locale={locale}/>

分页组件汉化:

//引入文件 import { ConfigProvider, message } from 'antd';

<ConfigProvider locale={zhCN}>


</ConfigProvider>

另外对于页面顶部的搜索功能,我们可以使用Form实现,相关的字段值设置为一个对象.在Form上面绑定onFieldsChange方法

const [searchObj, setSearchobj] = useState({
    username: '',
    organizationCode: 0,
    organizationOrgRoleRelationId: 0,
    openFlag: ''
})


const onChangeVal = (allval) => {

    const searchVal = Object.assign(searchObj, {
      username: allval[0].value,
      organizationCode: allval[1].value,
      organizationOrgRoleRelationId: allval[2].value,
      openFlag: allval[3].value
    })
    setSearchobj(searchVal)

  }
  
  
  <Form
    className="mo-form-search"
    onFieldsChange={(changedFields, allFields) => {
      onChangeVal(allFields);
    }}
    onFinish={handleSubmitSearchForm}
    colon={false}
  >


 </Form>

点击搜索的时候,将相关的表单字段值通过payload传递出去,请求接口即可.以上这些是在开发后台CRM系统时候遇到的一些相关问题.做一下记录,以免后续继续踩坑.