美文网首页
Dva.js总结

Dva.js总结

作者: 年轻人多学点 | 来源:发表于2021-01-20 17:37 被阅读0次

1.why Dva

dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念,全部代码不到 100 行。dva 实现上尽量不创建新语法,而是用依赖库本身的语法,比如 router 的定义还是用 react-router 的 JSX 语法的方式(dynamic config 是性能的考虑层面,之后会支持)。
他最核心的是提供了 app.model 方法,用于把 reducer, initialState, action, saga 封装到一起

app.model({
  namespace: 'products',
  state: {//State 表示 Model 的状态数据
    list: [],
    loading: false,
  },
  subscriptions: [
    function(dispatch) {
      dispatch({type: 'products/query'});//触发 action 的函数,action 是改变 State 的唯一途径
    },
  ],
  effects: {//Effect 被称为副作用,在我们的应用中,最常见的就是异步操作
    ['products/query']: function*() {
      yield call(delay(800));
      yield put({
        type: 'products/query/success',
        payload: ['ant-tool', 'roof'],
      });
    },
  },
//在dva中reducers聚合积累的结果是当前model的state 对象。通过actions中传入的值,
//与当前 reducers 中的值进行运算获得新的值(也就是新的 state)
  reducers: {
    ['products/query'](state) {
      return { ...state, loading: true, };
    },
    ['products/query/success'](state, { payload }) {
      return { ...state, loading: false, list: payload };
    },
  },
});

2.简单明了的Dva数据流向

数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State

[图片上传失败...(image-57ff75-1611135362899)]

3.Dva Router控制

dva 实例提供了 router 方法来控制路由,使用的是react-router

const app = dva();
import { Router, Route } from 'dva/router';
app.router(({history}) =>
  <Router history={history}>
    <Route path="/" component={HomePage} />
  </Router>
);

4.dva 应用的最简结构(带 model)

dva 提供多个 effect 函数内部的处理函数,比较常用的是 call 和 put。
call:执行异步函数
put:发出一个 Action,类似于 dispatch

课堂实战

// 创建应用
const app = dva();

// 注册 Model
app.model({
  namespace: 'count',
  state: 0,
  reducers: {
    add(state) { return state + 1 },
  },
  effects: {
    *addAfter1Second(action, { call, put }) {
      yield call(delay, 1000);//异步操作
      yield put({ type: 'add' });//类似于dispatch发action
    },
  },
});

// 注册视图
app.router(() => <ConnectedApp />);

// 启动应用
app.start('#root');

image.png

5.AntDesignPro1.0项目中的Dva

1.index.js

const app = dva({
  history: createHistory(),//history可以用来跳转路由内含location属性,这里修改history默认接口,其他接口不变----初始化
});

// 2\. Plugins
app.use(createLoading());//加载插件这里应该加载的是加载动画插件

// 3\. Register global model
app.model(require('./models/global').default);//将src/modles里面的东西灌进去,通过namespace取

// 4\. Router
app.router(require('./router').default);//全局挂载路由信息

// 5\. Start
app.start('#root');

export default app._store; 

2.router.js

export const getRouterData = app => {
    const routerConfig = {
        '/': {
            component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
        },
        '/person/personbasetwo': {//添加路径指向引入的组件,这条数据会被getRoutes函数渲染成真正的<Route>包裹的路由
          component: dynamicWrapper(app, ['personbaseTwo'], () => import('../routes/Person/PersonBaseTwo')),
        },
        '/person/baseInfo/:id': {//dynamicWrapper函数会吧[]里面数据放到app的model属性里,app是dva的实例
          component: dynamicWrapper(app, ['personbase'], () => import('../routes/Person/PersonBase/BaseInfo')),
        },
        ·······

3.connect连接model

/*dva的实例app中应该导入了所有的model,好像是在router中导入的,
这里用解构赋值从model中取值,为组件导入props,loading为dva提供的动画插件*/
@connect(({ personbaseTwo, loading }) => ({
  personbaseTwo,
  searchLoading: loading.effects['personbaseTwo/getList'],
//loding被这个异步函数影响,异步操作中就为ture,结束就为false
  loading: loading.effects['personbaseTwo/listpage'],
}))//从model中取数据生成自己想要的对象结构通过@修饰器放到下面组件中去
class personbaseTwo extends Component {
  constructor(props){
    super(props);
    this.state = {
    }
  }
  componentWillMount(){//组件将要渲染时拿到默认的一页多少条和当前页这些数据
    const { personbaseTwo:{pagination} }= this.props;
    const { page,pageSize } = pagination;
    this.props.dispatch({//转到namespace为personbaseTwo下面的listpage方法拿到页码为page的数据
      type:'personbaseTwo/listpage',//接口根据page只去此页数据
      payload:{
        page,
        pageSize,
      },
    });
  }
·······

4.跳转路由

onOk() {//点击确定执行的函数
          const {id}= record;
          than.props.dispatch(routerRedux.push({//用来跳转路由的
            pathname: `/person/baseInfoTwo/${id}`,//用这个pathname重新渲染路由页面并传ID
          }))
        },

dva请求接口成功后的回调提示

发dispatch的时候带一个callback

dispatch({
          type:'upImgModel/upImg',
          payload:{
            from:'DEFAULT',
            name:values.name,
            base64:url.replace(/^data:image\/\w+;base64,/, ""),
            dimension:JSON.stringify({
              width: width,
              heigh: height
              }),
          },
          callback: (state, msg) => {
            if(state === 'success') {
                Toast.success(msg,2,null,false)
                const url = sessionStorage.getItem("returnUrl")?sessionStorage.getItem("returnUrl"):'/Signature'
                router.push(url)
            } else {
                Toast.fail(msg,2,null,false)
            }
          }
        })

当判断code成功的时候 执行回调

 effects: {
    *upImg({ payload,callback }, { call, put }) {
      const response = yield call(postImg, payload);
      let reg = new RegExp(/0000$/, 'i')
      if(reg.test(response.code)) {
        yield put({
          type: 'save',
          payload: response.data
        });
        yield callback('success', '上传图片成功')
      }else{
        let { message="图片上传失败"} = response
        yield callback('error',message)
      }

    }
  },

dispatch函数返回的是Promise

dispatch函数执行后返回是一个Promise
effects里面调用的函数可以返回值
返回值相当于这个Promise里resolve(这个值)。可以被.then的第一个回调参数拿到

 effects: {
    upImg({ payload,callback }, { call, put }) {
        return "success"
    }
dispatch({
          type:'upImgModel/upImg',
          payload:{}
          }).then((res)=>console.log(res)) //"success"

dispatch的同步写法

async componentDidMount() {
    const res = await dispatch({
                         type:'upImgModel/upImg',
                         payload:{}
                        })
}

相关文章

  • Dva.js总结

    1.why Dva dva 是基于现有应用架构 (redux + react-router + redux-sag...

  • dva.js的使用与说明——项目总结

    安装一个dva.js+react.js的项目 // Install dva-cli$ npm install dv...

  • dva.js 上手

    dva.js 简介 dva 是阿里前端架构师 sorrycc 带 team 研发的一套轻量级前端框架,其目的是尽量...

  • dva.js 上手

    初始化 安装 dva-cli 用于初始化项目: 创建项目目录,并进入该目录: 初始化项目: 然后运行 npm st...

  • dva.js 解读

    学习了dva,感觉好棒,在使用redex、redux-thunk中的中的疑问在dva中都有效的解决了。1、mode...

  • Dva.js 快速上手指南

    先说些废话 最近在开发React技术栈的项目产品,对于数据状态的管理使用了Dva.js,作为一个资深的ow玩家,我...

  • dva.js 源码理解

    一. 先从官方快速上手 dva-cli 说起,建立起工程,参考 dva官网, 然后打开 index.js看到下面,...

  • dva.js学习梳理集

    不知大家学 react 或 dva 时会不会有这样的疑惑: es6 特性那么多,我需要全部学会吗? react c...

  • dva.js setInterval 倒计时

    参考:https://dvajs.com/guide/introduce-class.html#reducer c...

  • dva.js和umi.js

    最近公司的项目有用到dva框架,这里做下学习总结;菜鸟一枚,如有错误,欢迎指正。 dva是什么 官网:dva.js...

网友评论

      本文标题:Dva.js总结

      本文链接:https://www.haomeiwen.com/subject/tbnkzktx.html