下面是model的基本结构

TypeScript

{
  namespace: String,
  // 命名空间名字,必填
  //namespace: 'global' 说明以下此处的dva命名空间为 global,即你调用的时候需要采用 global.XXX 的形式
  state: Object,
  // 状态 reducer: Object,
  // 同步更新 state 修改状态 effects: Object,
  // 副作用:处理异步逻辑
  //当数据需要从服务器获取时,需要发起异步请求,请求到数据之后,通过调用 Reducers更新数据到全局state
  subscriptions: Object
  // 订阅数据源
}

1.reducer

用来处理同步操作。如果不需要调接口时候,我们前台传递的 action(不懂的小伙伴不着急,下面有微讲解) 可以直接调用 reducers里的方法。

reducer是一个函数,接收state 和 action,返回老的或新的state。 即: save(state, action) {undefined return { …state, …action.payload }; },

state:为当前 Model 下的所有 state 值,可以 console.log(state) 看一下输出就知道了。

action:当前台页面需要进行数据操作时,就会创建一个 action,action 存放了传递过来需要对当前 state 进行改变的数据。

TypeScript

  reducers: {
      changeTitle(state, {
          payload: {
            num
          }
        ) {
          //changeTitle可以理解为一个方法名
          //payload:就是 action 里传递过来的数据。 
          //num 是传过来的,名字随便起,不是state中的num,这接收一个action 
          return {
            ...state,
            ...num
          }
          //return:返回的是新的 state。等于舍弃了旧的 state,重新 return 一个新的 state 作为当前 Model 的 state。 
          //一般情况下,我们要解开旧的 state,将它重新赋值给新的 state。...state 为 ES6 语法。
          //将操作完成得数据累加到 return 中。
          //同名的数据会覆盖,所以不用担心旧的 state 值会影响到新设置的值。 
          //不同名的数据会追加。
        },

TypeScript

//页面调用
//页面使用dispatch进行使用 
this.props.dispatch({
  type: 'pageModel/changeTitle',
  //namespace+需要调用的reducer方法
  payload: 'Hello World',
});

2.effects

    用来处理异步操作。如果需要调取接口的话,前台页面就需要调用 effects 里的方法。

    将数据取出来,在传递给 reducers 里的方法进行数据操作和同步 state。

Dva 中的异步操作都放到 effects 中管理,基于 Redux-saga 实现 Effect 是一个 Generator函数,内部使用 yield 关键字,标识每一步的操作

每一个 effect 都可以接收两个参数:

1、包含 dispatch 携带参数 payload 的 action 对象

2、dva 提供的 effect 函数内部的处理函数集

第二个参数提供的处理函数中,常用的有 call、put、select call: 执行异步函数 put: 发出一个 Action,类似于

dispatch 触发reducer改变state select: 返回 model 中的 state //用于从state里获取数据

1.call

TypeScript

service中异步请求(cardsService.js) request 是我们封装的一个网络请求库

TypeScript

async function deleteOne(data) { return request("queryFromApi", { data, method: "post", dataType: "payload" }) }

2.select

TypeScript

*deleteOne({ payload }, { select, put }) {   effects:{ const m = yield select((state) => state.test.num) //select就是用来选择上面state里的数据 }

3.put

TypeScript

yield put({    type: "addNum", // put:用来发出事件,即 action。一般调用 reducers 下的方法进行同步数据。 //type:该 Model 层里 reducers 下的方法名。 //payload:参数的传递。 payload: {   num: data, // 把后台返回的数据赋值给了num //假如那个reducer中方法是由这里effects去触发的,那个num名必须是这里名字num,如果reducer中方法不是这触发,那名字可随便起 return rsp; }, } }

3.subscriptions

TypeScript

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

4.connect

connect 连接 Model 和 Route 页面下的数据

dva 有提供 connect 方法。只要在每个 Routes 页面导入下面的代码即可。

TypeScript

import { connect } from 'dva';

对于组件:

我们在最后导出时使用 connect 进行与 Models 的连接。

TypeScript

export default connect(({index}) => ({index}))(IndexPage);

//解释一下 index:index 为 Model 层里面的 namespace。

前台调用 Model 层方法

TypeScript

const { dispatch } = this.props; //在 dva 中,可以通过 `this.props` 直接取得 `dispatch`

TypeScript

dispatch ({ type:'example/fetch', //指定哪个 model 层里面的哪个 方法 payload:{name:'exampleNew'}, //需要传递到 model 层里面的参数。 //payload 为固定用法(我自己的理解)。 })

5.parame和query传值

query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示

版权声明:本文为CSDN博主「跳跳的小古风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_43787651/article/details/112304132