Umi2.x升級到Umi3.x

修改依賴

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/*"]
}

注意:

  1. Umi 3 需要 Node 10.13或以上,配置了engines屬性則需修改對應的版本號
  2. Umi3.x內置了antd、dva,建議移除依賴,避免依賴版本衝突導致無法正常啓動項目
  3. 爲了有更好的 ts 提示,需配置 @@ 爲 [“src/.umi/*”]
  4. 建議移除node_modules文件夾,重新npm install

扁平化配置

umi2.x和umi3.x都是在.umirc.js 或 config/config.js中進行項目配置,且.umirc.js的優先級依舊高於config/config.js。不同的是umi3.x之後,採用扁平化配置,並且刪除或修改了部分配置,在此記錄下。

  1. 移除umi-plugin-react,同時antd、dva不再在plugins內配置,將其提取到同級,兩者都接收一個對象;
  2. 移除disableRedirectHoisttreeShaking(treeShaking已內置);
  3. cssLoaderOptions重命名爲cssLoaderlessLoaderOptions重命名爲lessLoader
  4. dynamicImport移除level和webpackChunkName屬性,loadingComponent重命名爲loading
  5. 修改 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

  1. 使用Form.useForm() 重寫 Form.create()

react 類組件使用useForm報錯
       如果在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進行數據狀態管理

未完待續…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章