关于umi dva的使用

1.配置,在config.js中开启配置

  dva: {
    immer: true, // 表示是否启用 immer 以方便修改 reducer
    hmr: true, // 表示是否启用 dva model 的热更新
  },

2.约定式的 model 组织方式

符合以下规则的文件会被认为是 model 文件,

·src/models 下的文件
·src/pages 下,子目录中 models 目录下的文件
·src/pages 下,所有 model.ts文件(不区分任何字母大小写)
比如:

+ src
  + models/a.ts
  + pages
    + home/models/index.js
    + mine/model.js

ps:根据约定,umi会默认把models文件下的index.js 作为dva,所以一般在一个模块或者路由下建一个models文件

3.如何使用?
比如我们在home模块下,新建modules/index.ts(这里使用了typescript),在index.ts中写入

import type { Reducer, Effect, Subscription } from 'umi'
import request from 'umi-request'
import { getSchool } from '@/api/api'
/**
 * @description 声明HomeModelState中state的数据类型
 */
export interface HomeModelState {
  name: string
  age: number
}
/**
 * @description 声明HomeModelType的数据类型
 */
export interface HomeModelType {
  namespace: 'home'
  state: HomeModelState
  reducers: { setName: Reducer<HomeModelState> }
  effects: { query: Effect }
  subscriptions: { setup: Subscription }
}
/**
 * @description 定义HomeModel
 */
const HomeModel: HomeModelType = {
  /**
   * @param namespace: 如果没有声明 namespace,会以文件名作为 namespace
   */
  namespace: 'home',
  state: {
    name: 'test',
    age: 12,
  },
  /**
   * @description  // reducers 用来处理同步操作,与Vuex 中mutions 中一样
   * @param state: HomeModelType的state对象
   * @param action:调用该方法传过来的值
   * @param setName:这里的名字根据实际用途命名,可以在reducers中无限添加函数
   */
  reducers: {
    setName(state: any, action: any) {
      state.name = action.payload
      return state
    },
  },
  /**
   * @description effects 用来处理异步操作,与Vuex 中actions 中一样,调用方法与reducers一样,这点与Vux不同
   * @param payload:调用query时传过来的参数,比如这里放的是http请求,需要在路由中传参数进来
   * @param put
   */
  effects: {
    *query({ payload }, { call, put }) {
        /**
       * @description 不使用call res与res1的写法一致 ,一般使用res的写法
       *
       */
      // 方式1
      const res = yield getSchool({ name: payload })
      // const res1 = yield request.post('/api/getNames', { data: { name: payload } })
      if (res.success) {
        yield put({
          type: 'setName',
          payload: {
            data: res.data,
          },
        })
      }
      /**
       * @description 使用call result与result1的写法一致 ,一般使用result的写法
       *
       */
      const result = yield call(getSchool, { data: { name: payload } })
      // const result1 = yield call(request.post, '/api/getNames',{data: {name: payload}})
      if (result.success) {
        yield put({
          type: 'setName',
          payload: {
            data: result.data,
          },
        })
      }
    },
  },
  /**
   * @description 定义在subscriptions的方法 只要符合条件的 全局触发,比如setup中的监听window的窗口变化,只要
   *  浏览器的窗口发生了变化,在任意一个路由中都能监听并触发
   */
  subscriptions: {
    setup({ dispatch }) {
      window.onresize = () => {
        dispatch({ type: 'setName', payload: Math.random() })
      }
    },
  },
}
export default HomeModel

4.如何调用dva封装的方法?
假设我们想在home/index.ts中调用

// 使用umi中的connect方法与路由进行连接,使用props 与dva中model中的state数据进行绑定
import { connect } from 'umi'
const namespace: string = 'home'
const Home = (props: any) => {
  const { name } = props
  const query = () => {
    props.query('test1')
  }
  return <div onClick={query}>{name}</div>
}

function masterProps(state: any) {
  const { name } = state[namespace]
  return {
    name
  }
}
const mapDispatchToProps = (dispatch: any) => {
  return {
    setName(payload: string) {
      const action = {
        type: `${namespace}/setName`,
        payload: payload
      }
      dispatch(action)
    },
    query(payload: string) {
      const action = {
        type: `${namespace}/query`,
        payload: payload
      }
      dispatch(action)
    }
  }
}
export default connect(masterProps, mapDispatchToProps)(Home)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值