梁满根 發表於 2019-7-20 14:33:00

DvaJS构建配置React项目与使用

<h1 style="text-align: center">DvaJS构建配置React项目与使用</h1>
<h2>一,介绍与需求分析</h2>
<h3>&nbsp;1.1,介绍</h3>
<p>dva 首先是一个基于&nbsp;redux&nbsp;和&nbsp;redux-saga&nbsp;的数据流方案,然后为了简化开发体验,dva 还额外内置了&nbsp;react-router&nbsp;和&nbsp;fetch,所以dva是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装。是由阿里架构师 sorrycc 带领 team 完成的一套前端框架。</p>
<h3>&nbsp;1.2,需求</h3>
<p>快速搭建基于react的项目(PC端,移动端)。</p>
<h2>二,DvaJS构建项目</h2>
<h3>2.1,初始化项目</h3>
<p>第一步:安装node</p>
<p>第二步:安装最新版本dva-cli</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> $ npm install dva-cli -<span style="color: rgba(0, 0, 0, 1)">g
</span><span style="color: rgba(0, 128, 128, 1)">2</span> $ dva -v</pre>
</div>
<p>第三步:<code>dva new</code>&nbsp;创建新应用</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> $ dva <span style="color: rgba(0, 0, 255, 1)">new</span> myapp</pre>
</div>
<p>也可以在创建项目目录myapp后,用<code class="bash">dva init初始化项目</code></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> $ dva init</pre>
</div>
<p>第四步:运行项目<code><br></code></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">$ cd myapp
</span><span style="color: rgba(0, 128, 128, 1)">2</span> $ npm start</pre>
</div>
<p>浏览器会自动打开一个窗口</p>
<p><img src="https://img2018.cnblogs.com/blog/1040068/201812/1040068-20181213123909876-330673805.png" alt=""></p>
<p>&nbsp;</p>
<h3>2.2,项目架构介绍</h3>
<div>|-mock&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//存放用于 mock 数据的文件&nbsp;</div>
<div>|-node_modules&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//项目包</div>
<div>|-public&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//一般用于存放静态文件,打包时会被直接复制到输出目录(./dist)</div>
<div>|-src&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//项目源代码<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-asserts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//用于存放静态资源,打包时会经过 webpack 处理</div>
<div>&nbsp; |&nbsp;&nbsp;|-caches&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//缓存<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-components&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//组件&nbsp;存放 React 组件,一般是该项目公用的无状态组件<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-entries&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//入口<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-models&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//数据模型&nbsp;存放模型文件<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-pages&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//页面视图<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-routes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//路由&nbsp;存放需要 connect model 的路由组件<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-services&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//服务&nbsp;存放服务文件,一般是网络请求等<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-test&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//测试<br>&nbsp;&nbsp;|&nbsp;&nbsp;|-utils&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//辅助工具&nbsp;工具类库<br>|-package.json&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//包管理代码<br>|-webpackrc.js&nbsp;&nbsp;&nbsp;//开发配置<br>|-tsconfig.json&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;ts配置<br>|-webpack.config.js&nbsp;//webpack配置&nbsp;</div>
<div>|-.gitignore //Git忽略文件</div>
<div>在dva项目目录中主要分3层,models,services,components,其中models是最重要概念,这里放的是各种数据,与数据交互的应该都是在这里。services是请求后台接口的方法。components是组件了。</div>
<h2>三,DvaJS的使用</h2>
<h3>3.1,DvaJS的五个Api</h3>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import dva from 'dva'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> import {message} from 'antd'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> import './index.css'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 1. Initialize 创建 dva 应用实例</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> const app =<span style="color: rgba(0, 0, 0, 1)"> dva();
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 2. Plugins 装载插件(可选)</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">app.use({
</span><span style="color: rgba(0, 128, 128, 1)">10</span>   onError: <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (error, action) {
</span><span style="color: rgba(0, 128, 128, 1)">11</span>   message.error(error.message || '失败', 5<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">});
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 3. Model 注册model</span>
<span style="color: rgba(0, 128, 128, 1)">16</span>app.model(require('../models/example').<span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 4. Router 配置路由</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> app.router(require('../routes/router').<span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">20</span>
<span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 5. Start 启动应用</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> app.start('#root'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> export <span style="color: rgba(0, 0, 255, 1)">default</span> app._store; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> eslint-disable-line 抛出</span></pre>
</div>
<h4 style="margin-left: 30px"><strong>1,app = dva(Opts):创建应用,返回 dva 实例。(注:dva 支持多实例)​</strong></h4>
<p style="margin-left: 30px">在<code>opts</code>可以配置所有的<code>hooks</code>&nbsp;</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> const app =<span style="color: rgba(0, 0, 0, 1)"> dva({
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 0, 1)">   history,
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 0, 1)">   initialState,
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">   onError,
</span><span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 0, 1)">   onHmr,
</span><span style="color: rgba(0, 128, 128, 1)">6</span> });</pre>
</div>
<p style="margin-left: 30px">这里比较常用的是,history的配置,一般默认的是<code>hashHistory</code>,如果要配置 history 为&nbsp;<code>browserHistory</code>,可以这样:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> import dva from 'dva'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">2</span> import createHistory from 'history/createBrowserHistory'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">3</span> const app =<span style="color: rgba(0, 0, 0, 1)"> dva({
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">history: createHistory(),
</span><span style="color: rgba(0, 128, 128, 1)">5</span> });</pre>
</div>
<ul>
<li style="list-style-type: none">
<ul>
<li><code>initialState</code>:指定初始数据,优先级高于 model 中的 state,默认是&nbsp;<code>{}</code>,但是基本上都在modal里面设置相应的state。</li>
</ul>
</li>
</ul>
<h4 style="margin-left: 30px"><strong>2,</strong>app.use(Hooks):配置 hooks 或者注册插件。</h4>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">app.use({
</span><span style="color: rgba(0, 128, 128, 1)">2</span>   onError: <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (error, action) {
</span><span style="color: rgba(0, 128, 128, 1)">3</span>   message.error(error.message || '失败', 5<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">5</span> });</pre>
</div>
<p style="margin-left: 30px">可以根据自己的需要来选择注册相应的插件</p>
<h4 style="margin-left: 30px"><strong>3,</strong>app.model(ModelObject):这里是数据逻辑处理,数据流动的地方。</h4>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span>   namespace: 'example',<span style="color: rgba(0, 128, 0, 1)">//<code>model</code>&nbsp;的命名空间,同时也是他在全局&nbsp;<code>state</code>&nbsp;上的属性,只能用字符串,我们发送在发送&nbsp;<code>action</code>&nbsp;到相应的&nbsp;<code>reducer</code>&nbsp;时,就会需要用到&nbsp;<code>namespace</code></span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span>   state: {},<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表示 Model 的状态数据,通常表现为一个 javascript 对象(当然它可以是任何值)</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span>   subscriptions: {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">语义是订阅,用于订阅一个数据源,然后根据条件 dispatch 需要的 action</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>   setup({ dispatch, history }) {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> eslint-disable-line</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span>   effects: {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Effect 被称为副作用,最常见的就是异步操作</span>
<span style="color: rgba(0, 128, 128, 1)">13</span>   *fetch({ payload }, { call, put }) {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> eslint-disable-line</span>
<span style="color: rgba(0, 128, 128, 1)">14</span>       yield put({ type: 'save'<span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span>   reducers: {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">reducers 聚合积累的结果是当前 model 的 state 对象</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">    save(state, action) {
</span><span style="color: rgba(0, 128, 128, 1)">20</span>       <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> { ...state, ...action.payload };
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> };</pre>
</div>
<h4 style="margin-left: 30px"><strong>4,</strong>app.router(Function):注册路由表,我们做路由跳转的地方</h4>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import React from 'react'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> import { routerRedux, Route ,Switch} from 'dva/router'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> import { LocaleProvider } from 'antd'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> import App from '../components/App/App'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> import Flex from '../components/Header/index'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> import Login from '../pages/Login/Login'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> import Home from '../pages/Home/Home'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> import zhCN from 'antd/lib/locale-provider/zh_CN'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> const {ConnectedRouter} =<span style="color: rgba(0, 0, 0, 1)"> routerRedux;
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> RouterConfig({history}) {
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   &lt;ConnectedRouter history={history}&gt;
<span style="color: rgba(0, 128, 128, 1)">14</span>       &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">15</span>         &lt;Route path="/login"component={Login} /&gt;
<span style="color: rgba(0, 128, 128, 1)">16</span>         &lt;LocaleProvider locale={zhCN}&gt;
<span style="color: rgba(0, 128, 128, 1)">17</span>         &lt;App&gt;
<span style="color: rgba(0, 128, 128, 1)">18</span>         &lt;Flex&gt;
<span style="color: rgba(0, 128, 128, 1)">19</span>             &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">20</span>             &lt;Route path="/"exact component={Home} /&gt;
<span style="color: rgba(0, 128, 128, 1)">21</span>             &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">22</span>         &lt;/Flex&gt;
<span style="color: rgba(0, 128, 128, 1)">23</span>         &lt;/App&gt;
<span style="color: rgba(0, 128, 128, 1)">24</span>         &lt;/LocaleProvider&gt;
<span style="color: rgba(0, 128, 128, 1)">25</span>       &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">26</span>   &lt;/ConnectedRouter&gt;
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> export <span style="color: rgba(0, 0, 255, 1)">default</span> RouterConfig;</pre>
</div>
<h4 style="margin-left: 30px"><strong>5,</strong>app.start(, opts)</h4>
<p style="margin-left: 30px">启动我们自己的应用</p>
<h3>3.2,DvaJS的十个概念</h3>
<h4 style="margin-left: 30px"><strong>1,</strong>Model</h4>
<p style="margin-left: 30px"><code>model</code>&nbsp;是&nbsp;<code>dva</code>&nbsp;中最重要的概念,<code>Model</code>&nbsp;非&nbsp;<code>MVC</code>&nbsp;中的&nbsp;<code>M</code>,而是领域模型,用于把数据相关的逻辑聚合到一起,几乎所有的数据,逻辑都在这边进行处理分发</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import Model from 'dva-model'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> import effect from 'dva-model/effect';</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> import queryString from 'query-string'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> import pathToRegexp from 'path-to-regexp'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> import {ManagementPage as namespace} from '../../utils/namespace'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">import {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">getPages,
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> } from '../../services/page'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> Model({
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">namespace,
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">subscriptions: {
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   setup({dispatch, history}) {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> eslint-disable-line</span>
<span style="color: rgba(0, 128, 128, 1)">14</span>       history.listen(location =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">15</span>         const {pathname, search} =<span style="color: rgba(0, 0, 0, 1)"> location;
</span><span style="color: rgba(0, 128, 128, 1)">16</span>         const query =<span style="color: rgba(0, 0, 0, 1)"> queryString.parse(search);
</span><span style="color: rgba(0, 128, 128, 1)">17</span>         const match = pathToRegexp(namespace + '/:action'<span style="color: rgba(0, 0, 0, 1)">).exec(pathname);
</span><span style="color: rgba(0, 128, 128, 1)">18</span>         <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (match) {
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">         dispatch({
</span><span style="color: rgba(0, 128, 128, 1)">20</span>            type:'getPages'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">            payload:{
</span><span style="color: rgba(0, 128, 128, 1)">22</span>                s:query.s || 10<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">23</span>                p:query.p || 1<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">24</span>                j_code:parseInt(query.j,10) || 1<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)">             }
</span><span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)">         });
</span><span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">28</span>
<span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)">      })
</span><span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 0, 1)">reducers: {
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)">    getPagesSuccess(state, action) {
</span><span style="color: rgba(0, 128, 128, 1)">34</span>       const {list, total} =<span style="color: rgba(0, 0, 0, 1)"> action.result;
</span><span style="color: rgba(0, 128, 128, 1)">35</span>       <span style="color: rgba(0, 0, 255, 1)">return</span> {...state, list, loading: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">, total};
</span><span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 0, 0, 1)">}, {
</span><span style="color: rgba(0, 128, 128, 1)">39</span> <span style="color: rgba(0, 0, 0, 1)">getPages,
</span><span style="color: rgba(0, 128, 128, 1)">40</span> })</pre>
</div>
<h4 style="margin-left: 30px"><strong>2,</strong>namespace</h4>
<p style="margin-left: 30px"><code>model</code>&nbsp;的命名空间,同时也是他在全局&nbsp;<code>state</code>&nbsp;上的属性,只能用字符串,我们发送在发送&nbsp;<code>action</code>&nbsp;到相应的&nbsp;<code>reducer</code>&nbsp;时,就会需要用到&nbsp;<code>namespace</code></p>
<h4 style="margin-left: 30px"><strong>3,</strong>State(状态)</h4>
<p style="margin-left: 30px">初始值,我们在&nbsp;<code>dva()</code>&nbsp;初始化的时候和在&nbsp;<code>modal</code>&nbsp;里面的&nbsp;<code>state</code>&nbsp;对其两处进行定义,其中&nbsp;<code>modal</code>&nbsp;中的优先级低于传给&nbsp;<code>dva()</code>&nbsp;的&nbsp;<code>opts.initialState</code></p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> dva()初始化</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> const app =<span style="color: rgba(0, 0, 0, 1)"> dva({
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>   initialState: { count: 1<span style="color: rgba(0, 0, 0, 1)"> },
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">});
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> modal()定义事件</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">app.model({
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>   namespace: 'count'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>   state: 0<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">10</span> });</pre>
</div>
<pre><span>Model中state</span>的优先级比初始化的低,但是基本上项目中的&nbsp;<code>state</code>&nbsp;都是在这里定义的</pre>
<h4 style="margin-left: 30px"><strong>4,</strong>Subscription</h4>
<p style="margin-left: 30px">Subscriptions 是一种从&nbsp;源&nbsp;获取数据的方法,它来自于 elm。语义是订阅,用于订阅一个数据源,然后根据条件 dispatch 需要的 action。数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> subscriptions: { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">触发器。setup表示初始化即调用。</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">    setup({dispatch, history}) {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>       history.listen(location =&gt; {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">listen监听路由变化 调用不同的方法</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span>         <span style="color: rgba(0, 0, 255, 1)">if</span> (location.pathname === '/login'<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>          <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">清除缓存</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span>         } <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">          dispatch({
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>             type: 'fetch'
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">          });
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">      });
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   },</pre>
</div>
<h4 style="margin-left: 30px"><strong>5,</strong>Effects</h4>
<p style="margin-left: 30px">用于处理异步操作和业务逻辑,不直接修改&nbsp;<code>state</code>,简单的来说,就是获取从服务端获取数据,并且发起一个&nbsp;<code>action</code>&nbsp;交给&nbsp;<code>reducer</code>&nbsp;的地方。其中它用到了redux-saga里面有几个常用的函数。</p>
<ol>
<li>put &nbsp;用来发起一条action</li>
<li>call 以异步的方式调用函数</li>
<li>select 从state中获取相关的数据</li>
<li>take 获取发送的数据</li>
</ol>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">effects: {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>   *<span style="color: rgba(0, 0, 0, 1)">login(action, saga){
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>       const data = yield saga.call(effect(login, 'loginSuccess', authCache), action, saga);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"><strong>call</strong> 用户调用异步逻辑 支持Promise</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span>       <span style="color: rgba(0, 0, 255, 1)">if</span> (data &amp;&amp;<span style="color: rgba(0, 0, 0, 1)"> data.token) {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>         yield saga.put(routerRedux.replace('/home'));<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">put 用于触发action 什么是action下面会讲到</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>   *<span style="color: rgba(0, 0, 0, 1)">logout(action, saga){
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>       const state = yield saga.select(state =&gt; state);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">select 从state里获取数据</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span>   },</pre>
</div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">reducers: {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">    add1(state) {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>       const newCurrent = state.current + 1<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>       <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> { ...state,
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>         record: newCurrent &gt; state.record ?<span style="color: rgba(0, 0, 0, 1)"> newCurrent : state.record,
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">      current: newCurrent,
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">      };
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">    minus(state) {
</span><span style="color: rgba(0, 128, 128, 1)">10</span>       <span style="color: rgba(0, 0, 255, 1)">return</span> { ...state, current: state.current - 1<span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">effects: {
</span><span style="color: rgba(0, 128, 128, 1)">14</span>   *<span style="color: rgba(0, 0, 0, 1)">add(action, { call, put }) {
</span><span style="color: rgba(0, 128, 128, 1)">15</span>       yield put({ type: 'add1'<span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 128, 128, 1)">16</span>       yield call(delayDeal, 1000<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">17</span>       yield put({ type: 'minus'<span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">19</span>   },</pre>
</div>
<p style="margin-left: 30px">如果<code>effect</code>与<code>reducers</code>中的<code>add</code>方法重合了,这里会陷入一个死循环,因为当组件发送一个<code>dispatch</code>的时候,<code>model</code>会首先去找<code>effect</code>里面的方法,当又找到<code>add</code>的时候,就又会去请求<code>effect</code>里面的方法。</p>
<p style="margin-left: 30px">这里的&nbsp;delayDeal,是我这边写的一个延时的函数,我们在&nbsp;<code>utils</code>&nbsp;里面编写一个&nbsp;<code>utils.js</code></p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 128, 0, 1)"> *超时函数处理
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 128, 0, 1)"> * @param timeout:timeout超时的时间参数
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 128, 0, 1)"> * @returns {*} :返回样式值
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> export <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> delayDeal(timeout) {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">    setTimeout(resolve, timeout);
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">});
</span><span style="color: rgba(0, 128, 128, 1)">10</span> }</pre>
</div>
<p style="margin-left: 30px"><strong>接着我们在&nbsp;<code>models/example.js</code>&nbsp;导入这个&nbsp;<code>utils.js</code></strong></p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> import { delayDeal} from '../utils/utils';</pre>
</div>
<h4 style="margin-left: 30px"><strong>6,</strong>Reducer</h4>
<p style="margin-left: 30px">以<code>key/value</code>&nbsp;格式定义&nbsp;<code>reducer</code>,用于处理同步操作,唯一可以修改&nbsp;<code>state</code>&nbsp;的地方。由&nbsp;<code>action</code>&nbsp;触发。其实一个纯函数。</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)"> reducers: {
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 0, 1)">    loginSuccess(state, action){
</span><span style="color: rgba(0, 128, 128, 1)">3</span>       <span style="color: rgba(0, 0, 255, 1)">return</span> {...state, auth: action.result, loading: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">5</span>   }</pre>
</div>
<h4 style="margin-left: 30px"><strong>7,</strong>Router</h4>
<p style="margin-left: 30px"><code>Router</code>&nbsp;表示路由配置信息,项目中的&nbsp;<code>router.js</code></p>
<h4 style="margin-left: 30px"><strong>8,</strong>RouteComponent</h4>
<p style="margin-left: 30px"><code>RouteComponent</code>&nbsp;表示&nbsp;<code>Router</code>&nbsp;里匹配路径的&nbsp;<code>Component</code>,通常会绑定&nbsp;<code>model</code>&nbsp;的数据</p>
<h4 style="margin-left: 30px"><strong>9,</strong>Action:表示操作事件,可以是同步,也可以是异步</h4>
<p style="margin-left: 30px"><code>action</code>&nbsp;的格式如下,它需要有一个&nbsp;<code>type</code>&nbsp;,表示这个&nbsp;<code>action</code>&nbsp;要触发什么操作;<code>payload</code>则表示这个&nbsp;<code>action</code>&nbsp;将要传递的数据</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">2</span>      type: namespace + '/login'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 0, 1)">   payload: {
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">          userName: payload.userName,
</span><span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 0, 1)">          password: payload.password
</span><span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">7</span>}</pre>
</div>
<p style="margin-left: 30px">构建一个<code>Action</code>&nbsp;创建函数,如下:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> goLogin(payload) {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> let loginInfo =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>             type: namespace + '/login'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">            payload: {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">            userName: payload.userName,
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">            password: payload.password
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">            }
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">          }
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> loginInfo
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我们直接dispatch(goLogin()),就发送了一个action。</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> dispatch(goLogin())</pre>
</div>
<h4 style="margin-left: 30px"><strong>10,</strong>dispatch&nbsp;</h4>
<p style="margin-left: 30px"><code>type dispatch = (a: Action) =&gt; Action</code></p>
<p style="margin-left: 30px">dispatching function 是一个用于触发 action 的函数,action 是改变 State 的唯一途径,但是它只描述了一个行为,而 dipatch 可以看作是触发这个行为的方式,而 Reducer 则是描述如何改变数据的。</p>
<p style="margin-left: 30px">在 dva 中,connect Model 的组件通过 props 可以访问到 dispatch,可以调用 Model 中的 Reducer 或者 Effects,常见的形式如:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">dispatch({
</span><span style="color: rgba(0, 128, 128, 1)">2</span>    type: namespace + '/login', <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 如果在 model 外调用,需要添加 namespace,如果在model内调用 无需添加 namespace</span>
<span style="color: rgba(0, 128, 128, 1)">3</span>   payload: {}, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 需要传递的信息</span>
<span style="color: rgba(0, 128, 128, 1)">4</span> });</pre>
</div>
<ol>
<li>reducers 处理数据</li>
<li>effects &nbsp; 接收数据</li>
<li>subscriptions 监听数据</li>
</ol>
<h3>3.3,使用antd</h3>
<p style="margin-left: 30px">先安装&nbsp;<code>antd</code>&nbsp;和&nbsp;<code>babel-plugin-import</code></p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> npm install antd babel-plugin-import --<span style="color: rgba(0, 0, 0, 1)">save
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 0, 1)"># 或
</span><span style="color: rgba(0, 128, 128, 1)">3</span> yarn add antd babel-plugin-import</pre>
</div>
<p style="margin-left: 30px"><code>babel-plugin-import</code>&nbsp;也可以通过&nbsp;<code>-D</code>&nbsp;参数安装到&nbsp;<code>devDependencies</code>&nbsp;中,它用于实现按需加载。然后在&nbsp;<code>.webpackrc</code>&nbsp;中添加如下配置:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">2</span>   "extraBabelPlugins"<span style="color: rgba(0, 0, 0, 1)">: [
</span><span style="color: rgba(0, 128, 128, 1)">3</span>   ["import"<span style="color: rgba(0, 0, 0, 1)">, {
</span><span style="color: rgba(0, 128, 128, 1)">4</span>       "libraryName": "antd"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">5</span>       "libraryDirectory": "es"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">6</span>       "style": <span style="color: rgba(0, 0, 255, 1)">true</span>
<span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 0, 0, 1)">    }]
</span><span style="color: rgba(0, 128, 128, 1)">8</span> <span style="color: rgba(0, 0, 0, 1)">]
</span><span style="color: rgba(0, 128, 128, 1)">9</span> }</pre>
</div>
<p style="margin-left: 30px">现在就可以按需引入 antd 的组件了,如&nbsp;<code>import { Button } from 'antd'</code>,Button 组件的样式文件也会自动帮你引入。</p>
<h3>3.4,配置.webpackrc</h3>
<p style="margin-left: 30px">1,entry是入口文件配置</p>
<p style="margin-left: 30px">单页类型:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> entry: './src/entries/index.js',</pre>
</div>
<p style="margin-left: 30px">多页类型:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> "entry": "src/entries/*.js"</pre>
</div>
<p style="margin-left: 30px">2,extraBabelPlugins&nbsp;定义额外的 babel plugin 列表,格式为数组。</p>
<p style="margin-left: 30px">3,env针对特定的环境进行配置。dev 的环境变量是?<code>development</code>,build 的环境变量是?<code>production</code>。</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> "extraBabelPlugins": ["transform-runtime"<span style="color: rgba(0, 0, 0, 1)">],
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> "env"<span style="color: rgba(0, 0, 0, 1)">: {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">development: {
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>       extraBabelPlugins: ['dva-hmr'<span style="color: rgba(0, 0, 0, 1)">],
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">    production: {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">      define: {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>         __CDN__: process.env.CDN ? '//cdn.dva.com/' : '/'<span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">10</span> }</pre>
</div>
<p style="margin-left: 30px">开发环境下的 extraBabelPlugins 是?<code>["transform-runtime", "dva-hmr"]</code>,而生产环境下是?<code>["transform-runtime"]</code></p>
<p style="margin-left: 30px">4,配置 webpack 的?externals?属性</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 配置 @antv/data-set和 rollbar 不打入代码</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> "externals"<span style="color: rgba(0, 0, 0, 1)">: {
</span><span style="color: rgba(0, 128, 128, 1)">3</span>   '@antv/data-set': 'DataSet'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">4</span>   rollbar: 'rollbar'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">5</span> }</pre>
</div>
<p style="margin-left: 30px">5,配置 webpack-dev-server 的&nbsp;proxy&nbsp;属性。 如果要代理请求到其他服务器,可以这样配:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">proxy: {
</span><span style="color: rgba(0, 128, 128, 1)">2</span>   "/api"<span style="color: rgba(0, 0, 0, 1)">: {
</span><span style="color: rgba(0, 128, 128, 1)">3</span>       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "target": "http://127.0.0.1/",</span>
<span style="color: rgba(0, 128, 128, 1)">4</span>       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "target": "http://127.0.0.1:9090/",</span>
<span style="color: rgba(0, 128, 128, 1)">5</span>       "target": "http://localhost:8080/"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">6</span>       "changeOrigin": <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">7</span>      "pathRewrite": { "^/api" : ""<span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">8</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">9</span>   },</pre>
</div>
<p style="margin-left: 30px">6,disableDynamicImport</p>
<p style="margin-left: 30px">禁用&nbsp;<code>import()</code>&nbsp;按需加载,全部打包在一个文件里,通过&nbsp;babel-plugin-dynamic-import-node-sync&nbsp;实现。</p>
<p style="margin-left: 30px">7,publicPath</p>
<p style="margin-left: 30px">配置 webpack 的&nbsp;output.publicPath&nbsp;属性。</p>
<p style="margin-left: 30px">8,extraBabelIncludes</p>
<p style="margin-left: 30px">定义额外需要做 babel 转换的文件匹配列表,格式为数组</p>
<p style="margin-left: 30px">9,outputPath</p>
<p style="margin-left: 30px">配置 webpack 的&nbsp;output.path&nbsp;属性。</p>
<p style="margin-left: 30px">打包输出的文件</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> config["outputPath"] = path.join(process.cwd(), './build/')</pre>
</div>
<p style="margin-left: 30px">10,根据需求完整配置如下:</p>
<p style="margin-left: 30px">文件名称是:.webpackrc.js,可根据实际情况添加如下代码:</p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> const path = require('path'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> const config =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>   entry: './src/entries/index.js'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   extraBabelPlugins: [['import', { libraryName: 'antd', libraryDirectory: 'es', style: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> }]],
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">env: {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">    development: {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>       extraBabelPlugins: ['dva-hmr'<span style="color: rgba(0, 0, 0, 1)">],
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">    },
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">    production: {
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">      define: {
</span><span style="color: rgba(0, 128, 128, 1)">12</span>         __CDN__: process.env.CDN ? '//cdn.dva.com/' : '/'<span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">externals: {
</span><span style="color: rgba(0, 128, 128, 1)">16</span>   '@antv/data-set': 'DataSet'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">17</span>   rollbar: 'rollbar'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">lessLoaderOptions: {
</span><span style="color: rgba(0, 128, 128, 1)">20</span>   javascriptEnabled: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">proxy: {
</span><span style="color: rgba(0, 128, 128, 1)">23</span>   "/api"<span style="color: rgba(0, 0, 0, 1)">: {
</span><span style="color: rgba(0, 128, 128, 1)">24</span>       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "target": "http://127.0.0.1/",</span>
<span style="color: rgba(0, 128, 128, 1)">25</span>       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> "target": "http://127.0.0.1:9090/",</span>
<span style="color: rgba(0, 128, 128, 1)">26</span>       "target": "http://localhost:8080/"<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">27</span>       "changeOrigin": <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)">},
</span><span style="color: rgba(0, 128, 128, 1)">30</span>   es5ImcompatibleVersions:<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">31</span>   disableDynamicImport: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">32</span>   publicPath: '/'<span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">33</span>   hash: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(0, 128, 128, 1)">34</span> <span style="color: rgba(0, 0, 0, 1)">extraBabelIncludes:[
</span><span style="color: rgba(0, 128, 128, 1)">35</span>   "node_modules"
<span style="color: rgba(0, 128, 128, 1)">36</span> <span style="color: rgba(0, 0, 0, 1)">]
</span><span style="color: rgba(0, 128, 128, 1)">37</span> <span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">38</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (module.exports.env !== 'development'<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">39</span>   config["outputPath"] = path.join(process.cwd(), './build/'<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 128, 1)">40</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">41</span> export <span style="color: rgba(0, 0, 255, 1)">default</span> config</pre>
</div>
<h4 style="margin-left: 30px">更多&nbsp;<code>.webpackrc</code>&nbsp;的配置请参考&nbsp;roadhog 配置。</h4>
<h3>3.5,使用antd-mobile</h3>
<p>先安装&nbsp;antd-mobile&nbsp;和&nbsp;<code>babel-plugin-import</code></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> npm install antd-mobile babel-plugin-import --save <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 或</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> yarn add antd-mobile babel-plugin-import</pre>
</div>
<p><code>babel-plugin-import</code>&nbsp;也可以通过&nbsp;<code>-D</code>&nbsp;参数安装到&nbsp;<code>devDependencies</code>&nbsp;中,它用于实现按需加载。然后在&nbsp;<code>.webpackrc</code>&nbsp;中添加如下配置:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">2</span>   <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">plugins</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: [
</span><span style="color: rgba(0, 128, 128, 1)">3</span>   [<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">import</span><span style="color: rgba(128, 0, 0, 1)">"</span>, { libraryName: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">antd-mobile</span><span style="color: rgba(128, 0, 0, 1)">"</span>, style: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">css</span><span style="color: rgba(128, 0, 0, 1)">"</span> }] // `style: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">` 会加载 less 文件
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">]
</span><span style="color: rgba(0, 128, 128, 1)">5</span> }</pre>
</div>
<p>现在就可以按需引入antd-mobile&nbsp;的组件了,如&nbsp;<code>import { DatePicker} from '</code>antd-mobile<code>'</code>,DatePicker 组件的样式文件也会自动帮你引入。</p>
<h2>四,整体架构</h2>
<div>
<div><ol>
<li>我们根据 <code>url</code> 访问相关的 <code>Route-Component</code>,在组件中我们通过 <code>dispatch</code> 发送 <code>action</code> 到 <code>model</code> 里面的 <code>effect</code> 或者直接 <code>Reducer</code></li>
<li>当我们将<code>action</code>发送给<code>Effect</code>,基本上是取服务器上面请求数据的,服务器返回数据之后,<code>effect</code> 会发送相应的 <code>action</code> 给 <code>reducer</code>,由<strong>唯一能改变</strong> <code>state</code> 的 <code>reducer</code> 改变 <code>state</code> ,然后通过<code>connect</code>重新渲染组件。</li>
<li>当我们将<code>action</code>发送给<code>reducer</code>,那直接由 <code>reducer</code> 改变 <code>state</code>,然后通过 <code>connect</code> 重新渲染组件。如下图所示:</li>
</ol></div>
</div>
<p><img src="https://img2018.cnblogs.com/blog/1040068/201812/1040068-20181213134636345-1589136271.png" alt=""></p>
<h3>数据流向</h3>
<p style="margin-left: 30px">数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过&nbsp;<code>dispatch</code>&nbsp;发起一个 action,如果是同步行为会直接通过&nbsp;<code>Reducers</code>&nbsp;改变&nbsp;<code>State</code>&nbsp;,如果是异步行为(副作用)会先触发&nbsp;<code>Effects</code>&nbsp;然后流向&nbsp;<code>Reducers</code>&nbsp;最终改变&nbsp;<code>State</code></p>
<p><strong>重置models里的数据:</strong></p>
<div class="cnblogs_code" style="margin-left: 30px">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> dispatch({type:namespace+'/set',payload:{mdata:[]}});</pre>
</div>
<pre>   set是内置的方法</pre>
<h2 style="margin-left: 30px">Dva官方文档&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;nginx代理部署Vue与React项目</h2>
<h2>五,问题记录</h2>
<h3>5.1,路由相关的问题</h3>
<p>1,使用match后的路由跳转问题,版本routerV4</p>
<p>match是一个匹配路径参数的对象,它有一个属性params,里面的内容就是路径参数,除常用的params属性外,它还有url、path、isExact属性。</p>
<p>问题描述:<span style="background-color: rgba(255, 255, 255, 1); color: rgba(255, 0, 0, 1)">不能跳转新页面或匹配跳转后,刷新时url所传的值会被重置掉</span></p>
<p><span style="background-color: rgba(255, 0, 0, 1)">不能跳转的情况</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> const {ConnectedRouter} =<span style="color: rgba(0, 0, 0, 1)"> routerRedux;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> RouterConfig({history}) {
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> const tests =({match}) =&gt;<span style="color: rgba(0, 0, 0, 1)">(
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   &lt;div&gt;
<span style="color: rgba(0, 128, 128, 1)"> 6</span>       &lt;Route exact path={`${match.url}/:tab`} component={Test}/&gt;
<span style="color: rgba(0, 128, 128, 1)"> 7</span>       &lt;Route exact path={match.url} component={Test}/&gt;
<span style="color: rgba(0, 128, 128, 1)"> 8</span>   &lt;/div&gt;
<span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">11</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   &lt;ConnectedRouter history={history}&gt;
<span style="color: rgba(0, 128, 128, 1)">13</span>       &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">14</span>         &lt;Route path="/login" component={Login}/&gt;
<span style="color: rgba(0, 128, 128, 1)">15</span>         &lt;LocaleProvider locale={zhCN}&gt;
<span style="color: rgba(0, 128, 128, 1)">16</span>         &lt;App&gt;
<span style="color: rgba(0, 128, 128, 1)">17</span>             &lt;Flex&gt;
<span style="color: rgba(0, 128, 128, 1)">18</span>               &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">19</span>               &lt;Route path="/test" component={tests }/&gt;
<span style="color: rgba(0, 128, 128, 1)">20</span>               <span style="color: rgba(255, 0, 0, 1)"> &lt;Route exact path="/test/bindTest" component={BindTest}/&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">21</span>            
<span style="color: rgba(0, 128, 128, 1)">22</span>               &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">23</span>             &lt;/Flex&gt;
<span style="color: rgba(0, 128, 128, 1)">24</span>         &lt;/App&gt;
<span style="color: rgba(0, 128, 128, 1)">25</span>         &lt;/LocaleProvider&gt;
<span style="color: rgba(0, 128, 128, 1)">26</span>       &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">27</span>   &lt;/ConnectedRouter&gt;
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">29</span> }</pre>
</div>
<p>路由如上写法,使用下面方式不能跳转,但是地址栏路径变了</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> import { routerRedux} from 'dva/router'<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">...
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.dispatch(routerRedux.push({
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>      <span style="color: rgba(255, 0, 0, 1)"> pathname: '/test/bindTest',
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">      search:queryString.stringify({
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...query,</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">      Code: code,
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">      Name: name
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">      })
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">    }));
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> ...</pre>
</div>
<p><span style="background-color: rgba(255, 0, 0, 1)">能跳转,但是刷新所传的参数被重置</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> const {ConnectedRouter} =<span style="color: rgba(0, 0, 0, 1)"> routerRedux;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> RouterConfig({history}) {
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> const tests =({match}) =&gt;<span style="color: rgba(0, 0, 0, 1)">(
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   &lt;div&gt;
<span style="color: rgba(0, 128, 128, 1)"> 6</span>      <span style="color: rgba(255, 0, 0, 1)"> &lt;Route exact path={`${match.url}/bindTest`} component={BindTest}/&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span>       &lt;Route exact path={`${match.url}/:tab`} component={Test}/&gt;
<span style="color: rgba(0, 128, 128, 1)"> 8</span>       &lt;Route exact path={match.url} component={Test}/&gt;
<span style="color: rgba(0, 128, 128, 1)"> 9</span>   &lt;/div&gt;
<span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   &lt;ConnectedRouter history={history}&gt;
<span style="color: rgba(0, 128, 128, 1)">14</span>       &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">15</span>         &lt;Route path="/login" component={Login}/&gt;
<span style="color: rgba(0, 128, 128, 1)">16</span>         &lt;LocaleProvider locale={zhCN}&gt;
<span style="color: rgba(0, 128, 128, 1)">17</span>         &lt;App&gt;
<span style="color: rgba(0, 128, 128, 1)">18</span>             &lt;Flex&gt;
<span style="color: rgba(0, 128, 128, 1)">19</span>               &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">20</span>               &lt;Route path="/test" component={tests }/&gt;
<span style="color: rgba(0, 128, 128, 1)">21</span>               &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">22</span>             &lt;/Flex&gt;
<span style="color: rgba(0, 128, 128, 1)">23</span>         &lt;/App&gt;
<span style="color: rgba(0, 128, 128, 1)">24</span>         &lt;/LocaleProvider&gt;
<span style="color: rgba(0, 128, 128, 1)">25</span>       &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">26</span>   &lt;/ConnectedRouter&gt;
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">28</span> }</pre>
</div>
<p>路由如上写法,使用下面方式可以跳转,但是刷新时所传的参数会被test里所传的参数重置</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">...
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.dispatch(routerRedux.push({
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>      <span style="color: rgba(255, 0, 0, 1)"> pathname: '/test/bindTest',
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">      search:queryString.stringify({
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...query,</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">          Code: code,
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">          Name: name
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">       })
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">}));
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> ...</pre>
</div>
<p><span style="color: rgba(0, 255, 0, 1)">&nbsp;解决办法如下:地址多加一级,跳出以前的界面</span></p>
<p>路由配置</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> const {ConnectedRouter} =<span style="color: rgba(0, 0, 0, 1)"> routerRedux;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> RouterConfig({history}) {
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> const tests =({match}) =&gt;<span style="color: rgba(0, 0, 0, 1)">(
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>   &lt;div&gt;
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 255, 0, 1)">      &lt;Route exact path={`${match.url}/bind/test`} component={BindTest}/&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span>       &lt;Route exact path={`${match.url}/:tab`} component={Test}/&gt;
<span style="color: rgba(0, 128, 128, 1)"> 8</span>       &lt;Route exact path={match.url} component={Test}/&gt;
<span style="color: rgba(0, 128, 128, 1)"> 9</span>   &lt;/div&gt;
<span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   &lt;ConnectedRouter history={history}&gt;
<span style="color: rgba(0, 128, 128, 1)">14</span>               &lt;Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">15</span>               &lt;Route path="/test" component={tests }/&gt;
<span style="color: rgba(0, 128, 128, 1)">16</span>               &lt;/Switch&gt;
<span style="color: rgba(0, 128, 128, 1)">17</span>   &lt;/ConnectedRouter&gt;
<span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">19</span> }</pre>
</div>
<p>调用</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">...
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.dispatch(routerRedux.push({
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>       <span style="color: rgba(0, 255, 0, 1)">pathname: '/test/bind/test1',
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">      search:queryString.stringify({
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>         <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...query,</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">      Code: code,
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">      Name: name
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">      })
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">    }));
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> ...</pre>
</div>
<h3>&nbsp;5.2,箭头函数this指向问题</h3>
<p>箭头函数的this定义:<strong>箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。</strong></p><br><br>
来源:https://www.cnblogs.com/jackson-yqj/p/10108648.html
頁: [1]
查看完整版本: DvaJS构建配置React项目与使用