基于React、node的投票系统

 

1、开发前准备

1.1  技术选型

1.2  整体设计

1.3  构建开发

 

 

背景:

需要开发一个系统,让用户对角色进行投票,最后输出统计结果,投票采用两两对比,用户在喜爱的角色上点击即可进行投票,并且可以输出投票统计结果;用户可以查看角色信息详情,新增角色信息,并未对用户的权限作过多控制,所有用户可以新增角色和投票。

技术选型:

投票系统的后台逻辑比较简单,无非是增删改查操作,相比之下IO的使用比较多,需要和前端进行较多的交互,呈现出高IO低计算的需求,node及react成为适合的技术选型

整体设计:

采用node作web服务器,考虑这是小demo,mysql作数据服务器足够了,前端页面为了增加交互性和给用户更好的体验,采用SPA(单页面应用),前端采用react+react-router,react只是ui的框架,对于数据的处理可以配合alt(一种flux的实现),架构示意图:

 

构建开发:

react生态中,由于react框架本身完成的功能比较单一,需要配合其他很多的库或框架完成一套功能,而node具备的npm管理库的能力,这与react的开发需求正好匹配,在开发前需要将运行所依赖的库以及打包或开发所依赖的库加入package.json中去;

另外,一些纯前端的库文件,如bootstrap、jquery等,可以使用客户端的包管理软件bower进行管理,文件依赖在根目录下的bower.json中定义,下载路径默认是根目录下的bower_components,在具备git环境下执行bower install;

为了减小网络开销,js及css需要通过gulp工具各自合并,js文件通过gulp(browserify)构建,多个文件合并成一个,减小网络开销;browserify通过main.js为入口,将整个依赖树串起来,将整个业务js代码打包成bundle.js;css文件通过gulp(less)构建,在main.less中定义

gulp打包步骤:

1、将客户端的js库(通过bower工具管理)打成一个文件,gulp.src表示源文件路径,pipe表示流处理管道,最后合并到public/js/vendor.js

2、客户端依赖的第三方库(通过npm管理),打成一个文件

3、将业务文件打包,以main.js作为打包入口,去除所有第三方依赖,并且通过babel转换至ES5语法,打包至public/js/bundle.js

4、对业务代码的变化进行监控,当代码改变时,自动执行第三部的browserrify任务

5、对css文件打包,并且进行监控

 

 

 

技术点:

1、工程目录结构,采用node+react开发的模式,目录结构可以按下面进行设置

      root

           ---------app      前后端渲染采用同一套代码,组件代码都放在这个目录下

                      ---------components     组件定义

                      ---------actions             redux模式下的组件对应的action

                      ---------stores              redux模式下组件对应的store

                      ---------stylesheets      外部样式文件,react的样式还是需要单独定义

          ----------bower_components         客户端依赖的js库,通过bower管理

          ----------models                        数据库表模型定义文件

          ----------node_modules            通过npm管理的库文件目录

          ----------public                          客户端引用的资源文件目录,包括基于app目录打包生产的js,基于app/stylesheets下的less生成的css,图片

          ----------views                          客户端页面文件

          下面是文件

          -----------bower.json                bower工具配置文件,下载后的文件默认安装在项目根目录下的bower_components目录

          -----------config.js                    数据库连接信息配置文件

          -----------gulpfile.js                  gulp工具打包步骤配置文件

          -----------package.json            管理npm安装包

          -----------server.js                    node服务端运行文件

  

2、flux 数据单向流动模式,能同时运行在客户端及node端

      

 

      数据只能单向流动,最终view的改变只能由store的改变触发,而action可以在组件的代码里调用

      在alt框架下,每个组件拥有一个store及action文件,dispatcher不需过多关注

      action通常完成逻辑编排和调用,并根据调用结果产生相应的action,这些action能被配套的store监听.

  需要引入alt对象,通过generateActions方法定义action,addCharacter对外暴露

          

       store定义state的集合,监听action,根据不同action完成state的更新,store时单例对象,如果采用了服务端渲染,在node启动时,执行到import  XXstore时就会初始化,客户端在加载js时,执行到import  XXstore时,初始化

  需要引入alt对象及对应action,通过构造函数定义state,on+action名 构成的方法,监听action

    

  组件代码中,构造函数中一般要调用getState获取store初始状态,而store的监听与取消监听在生命周期的componentDidMount及componentWillUnmount阶段进行

        下面是自己的思考:服务端渲染的情况下,renderToString函数会执行组件的可视化阶段,即render之前(包括render),在浏览器端执行剩下的生命周期即可,为了保持store的一致,初始化阶段到render之间不应该有store的改变

   

 

3、react-router  路由,能同时运行在客户端及node端

      单页应用的场景下需要使用react-router,浏览器拦截请求,基于react计算出需要重新渲染的dom,对变化的部分进行渲染,这个过程不会向服务端发出页面请求,跳转过程中变化的组件会mount与unmount,并且浏览器的前进后退按钮,也不会整个页面重新加载,路由过程组件的store不会销毁,只会解绑监听,所以当浏览器后退到之前页面时,store的状态能保持。

       以下是我自己的推测:react 在设计之初就考虑服务端与客户端同构,即可以使用同一套代码,服务端不单是传统意义的web请求分发处理了,加上了服务端渲染的概念,将很多浏览器端干的活抢去干了。基于此,后续的react插件都支持服务端与客户端的运行,服务端渲染一般在首页加载,为了提升用户体验而需要采用的技术,其他时候采用客户端单独渲染就够用了。             

      

      页面跳转使用react-router提供的<Link>标签:  组件文件头中import {Link} from 'react-router';     跳转的地方使用<Link to='/shame'>Hall of Shame</Link>,   使用Link标签能够实现变化的dom刷新

       典型代码模块:

       路由文件route.js,定义了url与组件的匹配关系,这里的App组件是整个应用的根组件,一般要将SPA的可变组件嵌套进去:

  

        根组件app.js,注意可变组件的写法:

        

        服务端与客户端使用的是同一套代码,但路由入口不一样,服务端在server.js中定义,考虑所有的页面请求,都需要通过路由来获得,

  以下是我的总结:对于SPA场景,需要使用react-router,服务端可斟酌使用router;而对于普通的应用,就不需要使用react-router了,可以针对不同的url请求设置node中间件,路由到不同的静态页面文件,服务端渲染也可选择是否使用。

  

  客户端路由入口,需要通过构建工具打包至bundle.js中:

  

 

posted @ 2017-11-05 17:36  天下无双之盛世奇观  阅读(789)  评论(0编辑  收藏  举报