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进行数据状态管理

未完待续…

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