DVA 框架

2019-02-28  本文已影响0人  君莫叹人生如若初见

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

  1. 网络层(api接口,service服务)。
  2. 业务层(使用dva基于redux的数据流方案,在models中定义数据源,以及业务操作)
  3. 路由(使用dva基于react-route搭建页面路由,并且基于react-router搭建一个灵活的可控路由)
  4. 静态资源库的存放(文件夹assets中)
  5. 组件库的存放(文件夹components中)
  6. 页面存放(文件夹pages中)
  7. 工具类(文件夹utils)
XMLHttpRequest.withCredentials 有什么用?
跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等)
也可以简单的理解为,当前请求为跨域类型时是否在请求中协带cookie。

XMLHttpRequest.withCredentials 怎么用?
withCredentials属于XMLHttpRequest对象下的属性,可以对其进行查看或配置。
 <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的写法不同,具体看官网。
//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最佳实践

import { createHashHistory as createHistory } from 'history';
const app = dva({
  ...createLoading({
    effects: true,
  }),
  history: createHistory(),
  onError (error) {
    Toast.fail(error.message);
  },
});

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

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,让文件容易读取。

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

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

上一篇 下一篇

猜你喜欢

热点阅读