react+typescript+umi+dva+antd

简介: react+typescript+umi+dva+antd


背景

  • React
    前端三大框架之一。
  • typescript
    javascript的超集
  • Dva
    由阿里架构师 sorrycc 带领 team 完成的一套前端框架,在作者的 github 里是这么描述它的:”dva 是 react 和 redux 的最佳实践”。
  • Antd
    是阿里的一套开箱即用的中台前端/设计解决方案,UI框架。
  • Umi
    一套可插拔的企业级 react 应用框架,同样由dva作者 sorrycc 完成。他在Umi中引入了 UI 工具 antd,打包工具 roadhog,路由 react-router和状态管理器 dva,做到了可插拔机制。

创建一个umi应用

  1. 先安装node,再创建一个项目文件夹,通过脚手架创建umi项目
npx @umijs/create-umi-app

  1. 安装依赖
npm i
  1. 运行项目
npm run start

umi应用的路由

配置路由

在配置文件.umirc.ts中通过 routes 进行配置,格式为路由信息的数组。

routes: [
  { path: '/', component: '@/pages/Index' },
  { path: '/User', component: '@/pages/User' },
],

路由配置工程化

为了让代码更工程化,我们可以将路由配置单独拆分成一个文件

router.tsx

const router: any = [
  { path: '/', component: '@/pages/Index' },
  { path: '/User', component: '@/pages/User' },
]
export default router;

.umirc.ts

import { defineConfig } from 'umi';
import router from '@/router/router'; // 引入路由配置文件
export default defineConfig({
  nodeModulesTransform: {
    type: 'none',
  },
  routes: router,
});

约定式路由

除配置式路由外,Umi 也支持约定式路由。约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。

备注:约定式路由要先注释.umirc.ts里的routes配置

路由跳转

import { history } from 'umi';
// 跳转到指定路由
history.push('/list');
// 带参数跳转到指定路由
history.push('/list?a=b');
history.push({
  pathname: '/list',
  query: {
    a: 'b',
  },
});
// 跳转到上一个路由
history.goBack();

示例

Index.tsx

import React, { Component } from 'react'
import { history } from 'umi';
import styles from '@/assets/Style/Index.less'; // css module
export default class Index extends Component {
  // 路由跳转不带参数
  toLogin() {
    history.push('/login');
  }
  // 路由跳转带参数
  toLoginWithParameter() {
    history.push({
      pathname: '/login',
      query: {
        a: 'b',
      },
    })
  }
  render() {
    return (
      <div>
        <div className={styles.title}>首页</div>
        <div onClick={this.toLogin}>跳转不带参数</div>
        <div onClick={this.toLoginWithParameter}>跳转带参数</div>
      </div>
    )
  }
}

User.tsx

import React, { Component } from 'react'
export default class User extends Component {
  constructor(props: any) {
    super(props);
    console.log(props.location.query) // 打印路由参数
  }
  render() {
    return (
      <div>
        <h1 className={styles.title}>User</h1>
      </div>
    )
  }
}

安装插件集@umijs/preset-react

@umijs/preset-react是包含antd,dva等一系列插件的插件集,由于使用指令npx @umijs/create-umi-app创建的项目会自动添加此插件,所以之后不需要再安装@umijs/preset-react插件集包含的插件,否则启动项目的时候会报错

umi+antd

安装了插件集@umijs/preset-react之后,无需再做任何配置,直接可以按需加载antd并在组件中使用

import React, { Component } from 'react'
import { history } from 'umi';
import { Button } from 'antd'; // 引入antd组件
import styles from '@/assets/Style/Index.less'; // css module
export default class Index extends Component {
  // 路由跳转不带参数
  toUser() {
    history.push('/User');
  }
  // 路由跳转带参数
  toUserWithParameter() {
    history.push({
      pathname: '/User',
      query: {
        a: 'b',
      },
    })
  }
  render() {
    return (
      <div>
        <div className={styles.title}>首页</div>
        <Button type="primary" onClick={this.toUser}>跳转不带参数</Button>
        <Button type="primary" onClick={this.toUserWithParameter}>跳转带参数</Button>
      </div>
    )
  }
}

umi+dva

安装了插件集@umijs/preset-react之后,无需再做任何配置,直接可以使用dva

  1. 创建models目录以及model文件userInfo.tsx
import { Effect, ImmerReducer, Reducer, Subscription } from 'umi';
export interface UserInfoModelState {
  name: string;
  age: number;
}
export interface UserInfoModelType {
  namespace: 'userInfo';
  state: UserInfoModelState;
  effects: {
    query: Effect;
  };
  reducers: {
    save: Reducer<UserInfoModelState>;
    changeName: Reducer<UserInfoModelState>;
    // 启用 immer 之后
    // save: ImmerReducer<UserInfoModelState>;
  };
  subscriptions: { setup: Subscription };
}
const UserInfoModel: UserInfoModelType = {
  namespace: 'userInfo',
  state: {
    name: '张三',
    age: 20,
  },
  effects: {
    *query({ payload }, { call, put }) {
    },
  },
  reducers: {
    save(state, action) {
      return {
        ...state,
        ...action.payload,
      };
    },
    changeName(state, action) {
      return {
        ...state,
        ...action.payload,
      };
    },
    // 启用 immer 之后
    // save(state, action) {
    //   state.name = action.payload;
    // },
  },
  subscriptions: {
    setup({ dispatch, history }) {
      return history.listen(({ pathname }) => {
        if (pathname === '/') {
          dispatch({
            type: 'query',
          })
        }
      });
    }
  }
};
export default UserInfoModel;
  1. 组件中使用
  • class组件中使用
import React, { Component } from 'react'
import { connect, UserInfoModelState, Loading } from 'umi';
const connect1: any = connect;
@connect1(({ userInfo, loading }: { userInfo: UserInfoModelState; loading: Loading }) => ({
  userInfo,
  // dva-loading可以自动处理loading状态
  loading: loading.models.index,
}))
export default class User extends Component<any, any> {
  constructor(props: any) {
    super(props);
    console.log(props);
    this.state = {
      username: props.userInfo.name
    }
  }
  // 调用userInfo模块的reducers里的changeName方法
  private changeName = () => {
    const { dispatch } = this.props;
    dispatch({
        type: 'userInfo/changeName',
        payload:{
          name: '李四'
        }
    })
  }
  render() {
    return (
      <div>
        <div onClick={this.changeName}>更改用户名</div>
        <div className="title">用户名{this.props.userInfo.name}</div>
      </div>
    )
  }
}
  • 函数式组件中使用
import React, { FC } from 'react';
import { UserInfoModelState, ConnectRC, Loading, connect } from 'umi';
interface PageProps {
  userInfo: UserInfoModelState;
  loading: boolean;
}
const IndexPage: FC<PageProps> = (props) => {
  const handleClick = () => {
    const { dispatch } : any = props;
    dispatch({
      type: 'userInfo/changeName',
      payload:{
        name: '李四'
      }
    })
  }
  return (
    <div>
      <div onClick={handleClick}>更改用户名</div>
      <div className="title">用户名{props.userInfo.name}</div>
    </div>
  )
};
export default connect(({ userInfo, loading }: { userInfo: UserInfoModelState; loading: Loading }) => ({
  userInfo,
  loading: loading.models.index,
}))(IndexPage);
  • 项目目录

主要文章参考

https://www.icode9.com/content-4-652359.html

https://www.cnblogs.com/llcdbk/p/13029996.html

https://www.cnblogs.com/crazycode2/p/8593143.html

https://www.jianshu.com/p/86bd9fc0a219

https://segmentfault.com/q/1010000014835057

https://blog.csdn.net/YMX2020/article/details/106674097

https://blog.csdn.net/SCU_Cindy/article/details/82432971

初次尝试,摸坑永不止步,还有以下文章也参考了一下,拓展思路

https://www.cnblogs.com/jiawei-Wang/p/11400848.html

https://segmentfault.com/a/1190000021272819?utm_source=tag-newest

https://zhuanlan.zhihu.com/p/69200639

https://www.yuque.com/umijs/umi/dvamodels

https://www.codercto.com/a/25627.html

https://blog.csdn.net/deletGlobal/article/details/106183217

https://blog.csdn.net/YMX2020/article/details/106674097

https://zhuanlan.zhihu.com/p/92617879

http://www.caotama.com/294655.html

https://www.cnblogs.com/winfred/p/8216650.html

https://www.jianshu.com/p/21f8ed30e761

https://www.cnblogs.com/axel10/p/8503782.html

https://www.jianshu.com/p/81a5d4371f81

https://blog.csdn.net/sllailcp/article/details/89384328

https://www.cnblogs.com/lucas27/p/9292058.html

https://www.jianshu.com/p/c1a4166d9eda

https://blog.csdn.net/Leonardo_Zhu/article/details/96482371

https://www.jianshu.com/p/21f8ed30e761

目录
相关文章
|
1月前
|
前端开发 JavaScript 测试技术
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
49 0
|
1月前
|
前端开发 定位技术 API
react+typescript接入百度地图
react+typescript接入百度地图
45 0
|
1月前
|
JavaScript
react+typescript通过window.xxx挂载属性报错的解决方案
react+typescript通过window.xxx挂载属性报错的解决方案
34 0
|
2天前
|
前端开发 JavaScript 定位技术
Docusaurus框架——react+antd+echarts自定义mdx生成图表代码解释文档
Docusaurus框架——react+antd+echarts自定义mdx生成图表代码解释文档
13 0
|
1月前
|
前端开发 JavaScript 安全
使用React、TypeScript和Ant Design构建现代化前端应用
使用React、TypeScript和Ant Design构建现代化前端应用
27 0
|
2月前
|
开发框架 前端开发 JavaScript
探索前端开发中的跨平台框架React Native
本文将介绍前端开发中一种备受关注的跨平台框架React Native,通过比较原生应用与React Native的优缺点,探讨其在实际项目中的应用以及未来发展趋势。
|
2月前
|
开发框架 前端开发 JavaScript
从零开始学习React Native开发
React Native是一种基于React框架的移动端开发框架,使用它可以快速地构建出高性能、原生的移动应用。本文将从零开始,介绍React Native的基础知识和开发流程,帮助读者快速入门React Native开发,并实现一个简单的ToDo应用程序。
|
3月前
|
前端开发 JavaScript Android开发
跨端技术栈综合考察:深入剖析 UniApp、Flutter、Taro 和 React Native 的优势与限制
跨端技术栈综合考察:深入剖析 UniApp、Flutter、Taro 和 React Native 的优势与限制
|
3月前
|
前端开发 安全 Swift
【教程】React Native 应用中的代码混淆与安全性管理
【教程】React Native 应用中的代码混淆与安全性管理
48 0
|
1天前
|
开发框架 前端开发 JavaScript
【专栏】Flutter vs React Native:跨平台移动应用开发的比较
【4月更文挑战第27天】本文对比分析了Flutter和React Native两大跨平台移动开发框架。Flutter,由Google推出,以其接近原生的性能、快速启动和流畅滚动受青睐,适合高性能和高度定制的项目。React Native,Facebook维护,依赖JavaScript,虽性能受限,但热重载优势和丰富第三方库使其适合快速迭代的项目。两者都在拓展多平台应用,Flutter在桌面和Web,React Native在Windows。选择框架需考虑项目需求、团队技能和性能效率平衡。