umi和dva实战

上一篇文章:react redux使用

Umi 介绍

umi官网
Umi,中文可发音为乌米,是可扩展的企业级前端应用框架。Umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。然后配以生命周期完善的插件体系,覆盖从源码到构建产物的每个生命周期,支持各种功能扩展和业务需求。

Umi 是蚂蚁金服的底层前端框架,已直接或间接地服务了 3000+ 应用,包括 java、node、H5 无线、离线(Hybrid)应用、纯前端 assets 应用、CMS 应用等。他已经很好地服务了我们的内部用户,同时希望他也能服务好外部用户。

环境准备

首先得有 node,并确保 node 版本是 10.13 或以上。(mac 下推荐使用 nvm 来管理 node 版本)

$ node -v
v10.13.0

# 国内源
$ npm i yarn tyarn -g
# 后面文档里的 yarn 换成 tyarn
$ tyarn -v

# 阿里内网源
$ tnpm i yarn @ali/yarn -g
# 后面文档里的 yarn 换成 ayarn
$ ayarn -v
脚手架
先找个地方建个空目录。

$ mkdir myapp && cd myapp
通过官方工具创建项目,

$ yarn create @umijs/umi-app
# 或 npx @umijs/create-umi-app

安装依赖

$ yarn

启动项目

$ yarn start

umi和dva实战_第1张图片

约定式路由

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

如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages 目录拿到路由配置。

import {
      defineConfig } from 'umi';

export default defineConfig({
     
  nodeModulesTransform: {
     
    type: 'none',
  },
  //   routes: [
  //     { path: '/', component: '@/pages/index' },
  //   ],
  fastRefresh: {
     },
});

使用dva

直接编写dva代码,umi会自动引用dva,无需配置

dva官网

dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。

1.在src下新建目录models

接着新建文件count.js

export default {
     
  namespace: 'count', 命名空间名字,必填

  //state就是用来放初始值
  state: {
     
    number: 99,
  },
  // 能改变界面的action应该放这里,这里按官方意思不应该做数据处理,只是用来return state 从而改变界面
  reducers: {
     
    add(state, {
      payload }) {
     
      console.log('新增触发', payload);
      return {
      ...state, number: state.number + payload };
    },
  },
  // 与后台交互,处理数据逻辑的地方
  effects: {
     },
};

};

2.组件中使用

import {
      connect } from 'dva';

const Index = (props) => {
     
  console.log('props', props);
  const {
      number, add } = props;
  const handleAdd = () => {
     
    console.log('新增');
    add(1);
  };
  return (
    <div>
      counter:{
     number}
      <button onClick={
     handleAdd}>+1</button>
      <button>-1</button>
    </div>
  );
};
const mapStateProps = (state) => {
     
  return {
     
    number: state.count.number,
  };
};

const actionCreater = {
     
  add: (payload) => {
     
    return {
     
      type: 'count/add',
      payload,
    };
  },
};
export default connect(mapStateProps, actionCreater)(Index);


umi和dva实战_第2张图片

或者直接更简单的修改state

props.dispatch({
     
      type: 'count/add',
      payload: 5,
    });
import {
      connect } from 'dva';

const Index = (props) => {
     
  console.log('props', props);
  const {
      number } = props;
  const handleAdd = () => {
     
    console.log('新增', props.dispatch);
    props.dispatch({
     
      type: 'count/add',
      payload: 5,
    });
  };
  return (
    <div>
      counter:{
     number}
      <button onClick={
     handleAdd}>+1</button>
      <button>-1</button>
    </div>
  );
};
const mapStateProps = (state) => {
     
  return {
     
    number: state.count.number,
  };
};

const actionCreater = {
     
  add: (payload) => {
     
    return {
     
      type: 'count/add',
      payload,
    };
  },
};
export default connect(mapStateProps)(Index);

异步处理

const namespace = 'count';
const selectState = (state) => state[namespace];
export default {
     
  namespace: 'count', 命名空间名字,必填
  //state就是用来放初始值
  state: {
     
    number: 99,
    id: 999,
  },
  // 能改变界面的action应该放这里,这里按官方意思不应该做数据处理,只是用来return state 从而改变界面
  reducers: {
     
    add(state, {
      payload }) {
     
      console.log('新增触发', payload);
      return {
      ...state, number: state.number + payload };
    },
    overrideStateProps(state, {
      payload }) {
     
      return {
     
        ...state,
        ...payload,
      };
    },
    updateStateProps(state, {
      payload }) {
     
      const {
      name, value } = payload;
      return {
     
        ...state,
        ...{
      [name]: {
      ...state[name], ...value } },
      };
    },
  },
  // 与后台交互,处理数据逻辑的地方
  effects: {
     
    //生成器函数
    /**
     *
     * @param {*} action
     * @param {*} call //获取异步数据
     * @param {*} put //同步触发reducers中的函数
     * @param {*} select //获取state数据
     */
    *addAsync(action, {
      call, put, select }) {
     
      console.log('action');
      const {
      id } = yield select(selectState);
      //   console.log('id', id);

      //   let res = yield call();
      //   console.log('res', res);
      //   yield put({ type: 'add', res });
    },
  },
  subscriptions: {
     
    // 订阅监听,比如我们监听路由,进入页面就如何,可以在这写
    setup({
      dispatch, history, query }) {
     
      return history.listen(async ({
      pathname, search, query }) => {
     
        if (pathname === '/testdemo') {
     
          // 当进入testdemo这路由,就会触发fetchUser方法

          dispatch({
      type: 'fetchUser' });
        }
      });
    },
  },
};

umi和dva实战_第3张图片

你可能感兴趣的:(React相关)