lz在公司用react开发后台管理系统,大家都知道,后台管理系统,最主要的是数据的处理与后台的交互,实现支持App各种各样的功能。
既然说到数据处理,那么react的数据驱动和双向绑定就发挥了很大的作用;另外react的事件监听机制也是核心,通过触发事件触发函数中的方法,函数方法的罗列成为写后台管理系统的重点。
————————————————————————————————————————————————————
闲话不多说,直接说我的开发模式:
首先,来剖析一下项目的模式:
1、我所理解的react,它就是一个View,负责显示;
2、但是通过react我们可以再View层做很多事情,例如对数据的操作和事件的触发;
3、用react将controler层和View层结合,那么对于一个项目来说,缺少的只是Server了;
4、这里的Server我选择了node服务,node服务中有很多框架可供选择:koa、koa2、express等,对于我的项目,由于启动较早,我选用了express,如果现在让我重新做的话,我会毫不犹豫选择koa2;
5、因为所有的操作和请求都是在View层做的,所以服务并不是主要的组成部分,完全可以替换成nginx,httpserver等简单的服务;
6、项目目录中src是根本react本地开发目录,本地开发启动webpack服务,开发完成后最后打包生成静态文件js,css和img图片到dist文件夹中,这时候,只需要在express框架中配置一下静态文件目录指向dist文件夹;
通过整体架构的示意图,看出整个项目框架分为两部分,一内层react的View层,一是外层的node服务层,下面由内到外分别详细说一下内层外层和内外层之间的桥接;
1、内层react的View层可以理解为一个单页应用,在一个入口页面index.html中存在一个根元素<div id="root"></div>
所有的react组件都将渲染在这个根元素内部(下面称其为root元素),再由react引擎渲染成dom元素,了解react的童鞋都知道,react是虚拟的dom,是由js动态生成的dom元素,所以dom元素在root元素中是通过js脚本控制并且不断变化的;
a、这里有个疑问,怎么去控制dom的切换和局部刷新?
这个问题react已经帮我们做好;react的核心是数据驱动,数据驱动的概念是当数据发生变化,View随之发生改变,es5中提出的数据驱动原理,监听数据的读取触发事件,这个原理跟Vue.js中的数据双向绑定是大同小异;在后台管理系统中,从接口拿到数据,首先对数据进行处理(其实这一步我更愿意让后端的童鞋去做,直接拿到我想要的数据结构~),大多处理成一维数组、二维数组、对象、甚至字符串等,将这些数据在定义的变量中储存——setState()
方法,这样数据就会被监听,每次对数据进行处理后调用这个方法,那么根据双向绑定原理,页面的显示将会刷新,这里刷新的是与修改的数据有关的元素,也就是局部刷新;
b、还有对于新接触react的童鞋来说,肯定会存在这样一个疑问,整个项目只有一个html文件,怎么去跳转页面,进行页面间的切换?
确实,在整个react项目中,只有一个html文件,也就是上面所说的入口页面,也是存放root元素的页面。在上面已经提到,react所有dom都是虚拟的,由js动态生成的,这里说一下怎么去控制dom元素的生成与删除——react的前端路由;通过前端路由渲染不同的react组件来实现页面的切换;在我的项目里,每个页面是一个大的组件,当然这个大的组件可能包含很多小的组件,形成组件嵌套、复用,最后将这个大组件(页面)export出来,让前端路由获取,那么当URL的hash值发生该变的时候,触发事件去寻找与URL相匹配的路由,进而渲染与路由匹配的页面;
2、外层node服务,这个node框架仅仅是个server,当然还需要有个后端路由来render整个项目的入口页面–index.html,通过node服务的启动,这个入口页面就在服务器上跑起来了,剩下的事情交给react来做;
剩下要说的就是请求:对于后台管理系统来说,一个功能页面相对有大量的请求,各种方式的请求并存,获取数据get请求,提交数据post请求,表单,上传图片、文件,导出数据表格等等······
既然这么多的请求,则对于请求的封装是必不可少的,在我的项目中,选用了fetch作为请求工具,fetch请求是对ajax进行的封装, 下面贴出fetch原生支持率;
可以看出fetch的原生支持率并不高,好在我们项目只需要支持chrome 45以上,那么我就不用操心再引入一些库来对fetch进行封装了。这里也贴出对fetch进行封装的一些主流的方法;
引入下面这些 polyfill 后可以完美支持 IE8+ :
1.由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
2.引入 Promise 的 polyfill: es6-promise
3.引入 fetch 探测库:fetch-detector
4.引入 fetch 的 polyfill: fetch-ie8
5.可选:如果你还使用了 jsonp,引入 fetch-jsonp
6.可选:开启 Babel 的 runtime 模式,现在就使用 async/await
Fetch polyfill 的基本原理是探测是否存在 window.fetch 方法,如果没有则用 XHR 实现。这也是 github/fetch 的做法,但是有些浏览器(Chrome 45)原生支持 Fetch,但响应中有中文时会乱码,老外又不太关心这种问题,所以我自己才封装了 fetch-detector 和 fetch-ie8 只在浏览器稳定支持 Fetch 情况下才使用原生 Fetch。这些库现在每天有几千万个请求都在使用,绝对靠谱!
fetch请求是由页面(browser)发出去的,虽然chrome 45支持fetch,但是我也利用es6的Promise将fetch针对项目需求进行了封装,使其适应各种请求,使其在报错的时候在浏览器的控制台打出错误日志,这对开发很有帮助;
好了,以上所说框架的外围思路,也就是整体的大方向。基本就是这样,以后想到详细的再添加~
本人菜鸟,不喜轻喷,当然,欢迎大家多多说出自己的意见和建议,在这里我们共同进步~