react+typescript+umi+dva+antd

react+typescript+umi+dva+antd

  • 背景
  • 创建一个umi应用
    • umi应用的路由
      • 配置路由
      • 路由配置工程化
      • 约定式路由
      • 路由跳转
  • 安装插件集@umijs/preset-react
  • umi+antd
  • umi+dva

背景

  • 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
    

    react+typescript+umi+dva+antd_第1张图片
    react+typescript+umi+dva+antd_第2张图片

  2. 安装依赖

    npm i 
    
  3. 运行项目

    npm run start
    

    react+typescript+umi+dva+antd_第3张图片

umi应用的路由

配置路由

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

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

react+typescript+umi+dva+antd_第4张图片

路由配置工程化

为了让代码更工程化,我们可以将路由配置单独拆分成一个文件
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,
});

react+typescript+umi+dva+antd_第5张图片

约定式路由

除配置式路由外,Umi 也支持约定式路由。约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
react+typescript+umi+dva+antd_第6张图片
备注:约定式路由要先注释.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插件集包含的插件,否则启动项目的时候会报错
react+typescript+umi+dva+antd_第7张图片

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>
    )
  }
}


react+typescript+umi+dva+antd_第8张图片

umi+dva

安装了插件集@umijs/preset-react之后,无需再做任何配置,直接可以使用dva
react+typescript+umi+dva+antd_第9张图片

  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;
      };
      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;
    
  2. 组件中使用

  • 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);
    

    react+typescript+umi+dva+antd_第10张图片

  • 项目目录
    react+typescript+umi+dva+antd_第11张图片

主要文章参考
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

你可能感兴趣的:(react,react,typescript,前端,reactjs)