DVA 框架

最近公司有一个微信公众号的项目,于是花了一定的时间去搭建关于一个可以用于开发的微信公众号的架子。技术选型使用了阿里的dva。

  • 第一步,使用dva new wechat-public来初始化脚手架。
  • 第二步,完善当前脚手架。搭建一个架子无非就从这几点来操作:
  1. 网络层(api接口,service服务)。
  2. 业务层(使用dva基于redux的数据流方案,在models中定义数据源,以及业务操作)
  3. 路由(使用dva基于react-route搭建页面路由,并且基于react-router搭建一个灵活的可控路由)
  4. 静态资源库的存放(文件夹assets中)
  5. 组件库的存放(文件夹components中)
  6. 页面存放(文件夹pages中)
  7. 工具类(文件夹utils)
  • 网络层的构造。
    我们选取axios作为网络层请求的基本库。对其进行封装。在封装后,遇见了一个跨域请求的问题,原来是withCredentials犯的错误。
    经查询,有以下的解释,参考
XMLHttpRequest.withCredentials 有什么用?
跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等)
也可以简单的理解为,当前请求为跨域类型时是否在请求中协带cookie。

XMLHttpRequest.withCredentials 怎么用?
withCredentials属于XMLHttpRequest对象下的属性,可以对其进行查看或配置。
  • 数据的流向与页面路由
    利用dva自带的redux的封装,我们可以查看models层是mvc中的控制层的作用。首先通过在services中创建一个js文件,将我们的网络请求的服务暴露出来,然后再通过models层中的effects去交互。具体的可以去dva官网学习。
    期间遇到的问题:
    1.如何全局监听整个页面的路由。
    我们可以在react-routes中来操作。首先,我们创建一个app.js,来作为所有界面的父界面,然后,将其注册在route中。为以下的代码
 <ConnectedRouter history={history}>
      <App>
        <Switch>
          {/* 默认跳转到 service 页面 */}
          <Route exact path="/" render={() => <Redirect to="/service" />} />
            {
              Routes.map(({ name, path, exact = true,...dynamic_d }) => (
                <Route path={path} component={dynamic({app,...dynamic_d})} exact={exact} key={name}></Route>
              ))
            }
        </Switch>
        </App>
    </ConnectedRouter>

其中ConnectedRouter为dva-redux中暴露出来的Router,可以使用redux检测整个路由的变化,若我猜的不错,应该可以使用routerRedux去跳转路由,随后,使用在Switch外层包裹App,此App即为我们所需要封装的层。首先感谢这篇文章给我启发,随后,我们使用connect来将此组件包裹,connect为dva控制流的一个衔接。并且,我们需要在models中来注册这个model,这里需要注意一个问题,就是WithRouter的使用,由于这个页面是初始化页面,所以router还没有注册进来,我们用WithRouter让其props中的push,pop等方法注册进来,这样我们就可以在其中进行页面控制。随后,我们则可以通过绑定的app控制层来控制当前页面的路由。在models中使用:

    subscriptions: {
      setup({ dispatch, history }) {  // eslint-disable-line
      },
      setupHistory({ dispatch, history }) {
        history.listen((location) => {
            //当前监听全局的路由变化
            console.log(location)
        })
      }
    },
  1. 如何通过dva-loading来控制整个项目的loading。
    这个问题是一个比较需要关注的问题,因为之前我有用dva来做项目,由于当时对dva不是特别的熟悉,所以还没有将其发挥极致,最后loading是自己写一个界面,然后在每个界面都在request后面来使用,导致每个界面都需要首先注册一个state的isshow(举个例子)来控制loading的显示和隐藏。这极大的让整个项目的代码冗余,并且消耗时间。
    直到查询loading的控制后,发现整个组件,并且可以通过整个项目的数据流来控制。在index.js中注册这个后:
const app = dva({
  ...createLoading({
    effects: true,
  }),
  history: createHistory(),
  onError (error) {
    Toast.fail(error.message);
  },
});

随后,我们可以通过connect将loading注入到组件组件中,并且组件中会有

image.png
这个对象,然后我们可以通过global来整体控制整个项目的loading变化。并且,我们还可以通过effes/user来控制单个的异步请求,这样,我们就可以通过App来全局控制整个loading了,极大的减少了我们的工作量。在其他页面,只要connect就可以获取当前页面的异步请求,是不是特别的简单。
另外,我们需要注意一些路由的问题,v3和v4的写法不同,具体看官网。

  • 关于dva的动态加载组件的问题。
    在写这个架子之前,我有写一个mobx的控制流架子,里面动态组件是通过react-loadable,但是dva项目中已经有属于他的一个动态组件加载。那就是dynamic。
    如何使用? 这边刚好可以通过这个,把我们的按业务加载model也给写下来。
//tabs
const pagingTabs = [
    {
        name: '就诊服务',
        path: '/service',
        models: () => [
            import('models/service'),
          ],
        LoadingComponent:MyLoadingComponent,
        component:()=> import("pages/index")
    },
    {
        name: '个人中心',
        path: '/center',
        LoadingComponent:MyLoadingComponent,
        models: () => [
            import('models/center'),
          ],
        component:()=> import("pages/index")
    },
    {
        name: '医院信息',
        path: '/hospital',
        LoadingComponent:MyLoadingComponent,
        models: () => [
            import('models/hospital'),
          ],
        component:()=> import("pages/index")
    }
]

以上是一个路由的封装,将所有的路由都封装到这个pagingTabs里面,然后,我们通过上面的代码注册路由即可。
注意:在component中,我们不能够直接导入组件,而是要通过方法来回调出组件,这样才能够实现异步加载。
具体参考:React最佳实践

  • 关于dva无法使用二级路由的问题,一直报错:unexpect token <
    此错误困惑我很久,无法明白dva的问题。但也由于粗心的问题,第一我们得分清楚hashhistory和browerhistory的区别,然后,我们不能使用dva自带的history去注册路由,而是需要使用第三方库history,下载后,通过以下来注册:
import { createHashHistory as createHistory } from 'history';
const app = dva({
  ...createLoading({
    effects: true,
  }),
  history: createHistory(),
  onError (error) {
    Toast.fail(error.message);
  },
});

browerhistory 页面是无法出来的,会是空白页面或者报错,是因为项目中无法找到这个页面,我们得使用hash来让页面显示出来,记得在前面中加#

  • 关于dva的.webpackrc文件和.roadhogrc文件
    其实这两个文件相同,只是因为dva最新版把roadhogrc改为了webpackrc,其中语法可以参照roadhogrc中,我们在使用这个框架的时候,在github中去寻找这个库,这个只是creact-react-app中的一个扩展,让我们不用通过eject就可以自定义整个webpack。
    当然,我们还可以自己创建一个webpack.config.js来自定义webpack,比如我写了:
module.exports = (webpackConfig, env) => {
    // 别名配置
    webpackConfig.resolve.alias = {
      'pages':`${__dirname}/src/pages`,
      'components':`${__dirname}/src/components`,
      'utils':`${__dirname}/src/utils`,
      'routes':`${__dirname}/src/routes`,
      'models':`${__dirname}/src/models`,
      'services':`${__dirname}/src/services`,
      'models':`${__dirname}/src/models`,
      '@':`${__dirname}/src`
    }
    return webpackConfig
  }

来定义alias,让文件容易读取。

  • 关于html-plugin插件
    我们使用这个插件来定义我们整个项目的入口模板,并且可以通过他自动生成Html,通过filename来指定html生成的路径。此项目中使用entry.ejs来定义入口。

整个框架:dva + axios + antd-mobile + react-router + roadhog

另感谢这些作者:
React最佳实践系列 —— Dva 进阶之路由和动态加载
DVA框架统一处理所有页面的loading状态
ajax中的withCredentials使用效果
dva

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352