修改依賴
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進行數據狀態管理
未完待續…