最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 扫清dva的知识盲点

    正文概述 掘金(苻侑)   2021-03-18   1079

    扫清dva的知识盲点

    Dva 简介

    1. 借鉴 elm 的概念,Reducer,Effect 和 Subscription
    2. 框架,而非类库
    3. 基于 redux,react-router,redux-saga 的轻量级封装

    Dva 的特性

    1. 仅有 5 个 API,其用法我们会在之后详细介绍。
    2. 支持 HMR,支持模块的热更新。
    3. 支持 SSR (ServerSideRender),支持服务器端渲染。
    4. 支持 Mobile/ReactNative,支持移动手机端的代码编写。
    5. 支持 TypeScript,支持 TypeScript,毋庸置疑这个会是 Javascript 的一个趋势。
    6. 支持路由和 Model 的动态加载。

    Dva 的 5 个API

    扫清dva的知识盲点

    app = dva(Opts)

    创建应用,返回 dva 实例(注:dva 支持多实例)。
    opts 可以配置所有的 hooks

    const app = dva({
      history,
      initialState,
      onError,
      onAction,
      onStateChange,
      onReducer,
      onEffect,
      onHmr,
      extraReducers,
      extraEnhancers,
    });
    

    这里比较常用的是,history 的配置,一般默认的是hashHistory,如果要配置 history 为 browserHistory,可以这样:

    import createHistory from 'history/createBrowserHistory';
    const app = dva({
      history: createHistory(),
    });
    
    • 关于react-router 中的 hashHistorybrowserHistory 的区别大家可以看:react-router。
    • initialState:指定初始数据,优先级高于 model 中的 state,默认是 {},但是基本上都在 model 里面设置对应应的 state

    app.use(Hooks)

    配置 hooks 或者注册插件。 这里最常见的就是 dva-loading 插件的配置,

    import createLoading from 'dva-loading';
    
    // ...
    
    app.use(createLoading(opts));
    

    但是一般对于全局的 loading 我们会根据业务的不同来显示相应不同的 loading 图标,我们可以根据自己的需要来选择注册相应的插件。

    app.model(ModelObject)

    这个是你数据逻辑处理,数据流动的地方。 扫清dva的知识盲点 modaldva 里面与我们真正进行项目开发,逻辑处理,数据流动的地方。 这里面涉及到的 namespaceModaleffectsreducer 等概念都很重要,我们会在接下来的部分详细讲解。

    app.router(Function)

    注册路由表,我们做路由跳转的地方。
    一般都是通过下面的方式编写:

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

    但是如果你的项目特别的庞大,我们就要考虑到相应的性能的问题,但是入门可以先看一下这个。

    解决性能问题,其实就是对路由进行按需加载,实现起来也比较简单,就是使用了 require.ensure 这个方法来帮我们实现,同时我们也可以使用 ES6 module 的动态 import 来实现按需加载。不过动态 import 这个方法还在提案中,我们需要接着 babel 插件来帮我们实现,具体笔者就不展开了。

    app.start([HTMLElement], opts)

    启动应用,将我们的应用跑起来。

    Dva 九个概念

    State(状态)

    初始值,我们在 dva() 初始化的时候和在 model 里面的 state 对其两处进行定义,其中 model 中的优先级低于传给 dva()opts.initialState
    如下:

    // dva()初始化
    const app = dva({
      initialState: { count: 1 },
    });
    
    // modal()定义事件
    app.model({
      namespace: 'count',
      state: 0,
    });
    

    Action

    表示操作事件,可以是同步,也可以是异步
    action 的格式如下,它需要有一个 type ,表示这个 action 要触发什么操作;payload 则表示这个 action 将要传递的数据

    {
      type: String,
      payload: data,
    }
    

    我们通过 dispatch 方法来发送一个 action

    // Action
    // Action 表示操作事件,可以是同步,也可以是异步
    {
      type: String,
      payload: data
    }
    
    // 格式
    
    dispatch(Action);
    dispatch({ type: 'todos/add', payload: 'Learn Dva' });
    

    其实我们可以构建一个 Action 创建函数,如下

    function addTodo(text) {
      return {
        type: ADD_TODO,
        text
      }
    }
    //我们直接dispatch(addTodo()),就发送了一个action。
    dispatch(addTodo())
    

    action 更多内容可以查看文档:redux——action

    Model

    model 是 dva 中最重要的概念,ModelMVC 中的 M,而是领域模型,用于把数据相关的逻辑聚合到一起,几乎所有的数据,逻辑都在这边进行处理分发

    state

    这里的 state 跟我们刚刚讲的 state 的概念是一样的,只不过它的优先级比初始化的低,但是基本上项目中的 state 都是在这里定义的。

    namespace

    model 的命名空间,同时也是他在全局 state 上的属性,只能用字符串,我们在发送 action 到相应的 reducer 时,就会需要用到 namespace

    Reducer

    key/value 格式定义 reducer,用于处理同步操作,唯一可以修改 state 的地方。由 action 触发。其实一个纯函数。

    Effect

    用于处理异步操作和业务逻辑,不直接修改 state,简单的来说,就是获取从服务端获取数据,并且发起一个 action 交给 reducer 的地方。 其中它用到了redux-saga,里面有几个常用的函数。

    *add(action, { call, put }) {
      yield call(delay, 1000);
      yield put({ type: 'minus' });
    },
    

    扫清dva的知识盲点
    在项目中最主要的会用到的是 putcall

    Subscription

    subscription 是订阅,用于订阅一个数据源,然后根据需要 dispatch 相应的 action。
    app.start() 时被执行,数据源可以是当前的时间、当前页面的 url、服务器的 websocket 连接、history 路由变化、键盘事件等等。

    Router

    Router 表示路由配置信息,项目中的 router.js。

    export default function({ history }){
      return(
        <Router history={history}>
          <Route path="/" component={App} />
        </Router>
      );
    }
    

    RouteComponent

    RouteComponent 表示 Router 里匹配路径的 Component,通常会绑定 model 的数据。如下:

    import { connect } from 'dva';
    
    function App() {
      return <div>App</div>;
    }
    
    function mapStateToProps(state) {
      return { todos: state.todos };
    }
    
    export default connect(mapStateToProps)(App);
    

    整体架构

    我简单的分析一下这个图:
    扫清dva的知识盲点 首先我们根据 url 访问相关的 Route-Component,在组件中我们通过 dispatch 发送 actionmodel 里面的 effect 或者直接 Reducer
    当我们将 action 发送给 Effect,基本上是取服务器上面请求数据的,服务器返回数据之后,effect 会发送相应的 actionreducer,由唯一能改变 statereducer 改变 state ,然后通过 connect 重新渲染组件。
    当我们将 action 发送给 reducer,那直接由 reducer 改变 state,然后通过 connect 重新渲染组件。

    这样我们就能走完一个流程了。

    umi与 dva 和 doadhog 的关系

    以下比较引自官网:

    • roadhog 是基于 webpack 的封装工具,目的是简化 webpack 的配置
    • umi 可以简单地理解为 roadhog + 路由,思路类似 next.js/nuxt.js,辅以一套插件机制,目的是通过框架的方式简化 React 开发
    • dva 目前是纯粹的数据流,和 umi 以及 roadhog 之间并没有相互的依赖关系,可以分开使用也可以一起使用,更多可以参考:使用 umi 改进 dva 项目开发

    参考链接

    • umi 官网
    • roadhog介绍
    • dva 官网
    • webpack4.0 学习文档
    • Dva-React 应用框架在蚂蚁金服的实践
    • 10分钟 让你dva从入门到精通
    • 基于dva-cli&antd的react项目实战

     

    示例代码

    • dva-demo 项目示例代码
    • umi-demo 项目示例代码

    起源地下载网 » 扫清dva的知识盲点

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元