修改依赖
npm uninstall -S dva antd
npm uninstall -D umi-plugin-react
npm install -D umi@3 @umijs/preset-react
// package.json
"engines": {
"node": ">=10.13.0"
}
// tsconfig.json
"paths": {
"@/*": ["src/*"],
"@@/*": ["src/.umi/*"]
}
注意:
- Umi 3 需要 Node 10.13或以上,配置了engines属性则需修改对应的版本号
- Umi3.x内置了antd、dva,建议移除依赖,避免依赖版本冲突导致无法正常启动项目
- 为了有更好的 ts 提示,需配置 @@ 为 [“src/.umi/*”]
- 建议移除node_modules文件夹,重新npm install
扁平化配置
umi2.x和umi3.x都是在.umirc.js 或 config/config.js中进行项目配置,且.umirc.js的优先级依旧高于config/config.js。不同的是umi3.x之后,采用扁平化配置,并且删除或修改了部分配置,在此记录下。
- 移除umi-plugin-react,同时antd、dva不再在plugins内配置,将其提取到同级,两者都接收一个对象;
- 移除disableRedirectHoist和treeShaking(treeShaking已内置);
- cssLoaderOptions重命名为cssLoader,lessLoaderOptions重命名为lessLoader;
- dynamicImport移除level和webpackChunkName属性,loadingComponent重命名为loading;
- 修改 history 格式为 { type, options },eg: history: { type: ‘hash’ } 。
// https://umijs.org/config/
import theme from './theme.config';
import routes from './router.config';
export default {
antd: { },
dva: {
// 开启dva-immer,用于代理currentState和nextState之间的改变,即当前状态修改副本
immer: true,
// 开启模块热加载(热更新)
hmr: true,
},
// 开启路由动态加载
dynamicImport: {
loading: '@/components/PageLoading'
},
// 浏览器兼容
targets: {
ie: 11
},
// 开启文件hash后缀
hash: true,
// 路由相关配置
routes,
// 配置antd主题,实际上是配 less 变量。
theme,
// 启用 Hash 路由
history: {
type: 'hash'
},
// 指定react-router的base,部署到非根目录时需要配置
// base:'/',
// 指定webpack的publicPath,指向静态资源文件所在的路径
publicPath:'./',
// DefinePlugin 全局常量定义
define: { }
}
import all from umi
通过上述操作,我们可以正常启动项目,但在执行脚本后,dva和umi相关依赖都会提示引用不到。因为在Umi3.0之后,dva相关依赖都已经内置在umi中,umi依赖引用写法做了调整,所以我们需要修改代码层面的依赖引用。
- import { connect } from 'dva';
+ import { connect } from 'umi';
- import Link from 'umi/link';
+ import { Link } from 'umi';
- import router from 'umi/router';
- import { routerRedux } from 'dva/router';
+ import { history } from 'umi';
- router.push('/');
+ history.push('/');
- routerRedux.replace('/');
+ history.replace('/');
修正语法支持antd4.x
- 使用Form.useForm() 重写 Form.create()
如果在class Component中使用useForm,会遇到上图所示的报错信息,大概意思不允许在类组件中使用相关的hook钩子。所以我们要将class Component 改成function Component,以便支持useForm hook。
Form组件的onSubmit属性已重命名为onFinish,移除了getFieldDecorator。原本的initialValue、rules、getValueFromEvent等已作为Form.Item组件的属性来用。
import React from 'react';
import { Form, Input, Button } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import styles from './Login.less';
const LoginPage = () => {
const [ form ] = Form.useForm();
const login = values => {
// do something...
}
return (
<div className={styles.loginPage}>
<Form
form={ form }
onFinish={ login }>
<Form.Item
name="username"
rules={[ { required: true, message: '用户名不能为空!' } ]}
getValueFromEvent={ event => event.target.value.trim() }
>
<Input prefix={<UserOutlined/>} size="large" placeholder="请输入用户名" />
</Form.Item>
<Form.Item
name="password"
rules={[ { required: true, message: '密码不能为空!' } ]}
>
<Input.Password prefix={<LockOutlined/>} size="large" placeholder="请输入密码"/>
</Form.Item>
<Button type="primary" htmlType="submit" size="large" className={styles.loginButton}>
登录
</Button>
</Form>
</div>
)
}
export default LoginPage;
有个场景需要注意下,我们经常在modal(模态框)中使用表单进行信息的新增或编辑。在antd4.x之后使用useForm钩子,模态框消失后,调用resetFields是会恢复到第一次initialValues或initialValue的数据,所以不建议使用resetFields来清空表单。目前暂时只想到使用useEffect钩子在每一次显示modal(模态框)的时候,手动setFieldsValue初始化数据。
// antd4.x设置initialValues或者initialValue会导致调用resetFields无法清空数据,暂时使用setFieldsValue处理
useEffect(() => {
if(visible) {
form.setFieldsValue({ status: "1", isAdmin: "0", ...userInfo })
}
}, [ visible ]) // visible是modal的状态
使用useDispatch, useSelector进行数据状态管理
未完待续…