您的位置:首页 > Web前端 > React

ReactJS+Compass+Gulp+RESTful多页应用组件化开发

2016-01-12 17:54 483 查看

前言

我也是一个入坑的前端工程师,从一个无知的少年,变成了又一个无知的少年。一次一次觉得自己学的让自己兴奋的东西,总有另外一个西瓜让你丢掉这个芝麻。做出来好看不过css写起来好麻烦,响应式要自己写media query,css3适配要自己写,选择器父子嵌套很麻烦,Grid要自己写。不能统一管理变量(如颜色,字体大小等),之后学了sass觉得nb,写css方便多了(没有基础还是不行,css中一些原理还是要学习,各种position的区别,各种display的区别,BFC还有一些小而细的细节得钻研)。然而由出现了compass,据说是css界的jquery库,然后又学习了oocss, smacss巴拉巴拉如何写css能有更高的maintainability和reusability。JS方面,学了jQuery,我可以抬起头走路了,然后在实习的过程中,ReactJs, AngularJs, BackboneJs, Zepto, YUI, UnderscoreJS, CanJs, SeaJs一下子撑爆了我的任务表。具体哪种技术有什么优点,要使用过之后才能说得出来。如今40天完成的项目,我用了Compass 和 ReactJs可以在这里做一个总结,给后人一个模版,共同推进前端的发展。

这篇文章不讲解具体的技术细节如css的属性或者哪个js函数有什么用,而是带你一起来探讨如何组织项目文件以及其中的逻辑

欢迎来喷!:-(

项目结构

项目的资源文件的分布是 按资源类型 进行分布的。接下来的项目我会对组件采用 按组件 分布的方式。

样式

_base.scss: 储存项目的基础变量,如间距、颜色等

_helper.scss 辅助类,提供快速的css设置,如.text-center, .font-color-red, .full-width, padding-sm, margin-sm,理念与bootstrap中的快速浮动有关。

_layout.scss 包括了Grid的实现以及项目特有的布局类

_components.scss 组件实现具体的组件的样式

上述的文件将会由 compass compile -s compressed 编译成一个main.min.css文件,并且进行压缩,压缩后由68kb压缩到了30kb,自动取掉了注释的发布版本。对于组件类的命名,我借鉴的是BEM的命名法则。对于自己的项目,可以有自己命名方法论。

最后样式就是一个文件,包括所有的组件,做永久cache,并且用gulp-rev-append做MD5摘要方便修改后的缓存刷新

JS组件

脚本分类

display组件:从controller组件(父元素)中获得数据进行渲染

controller组件:维护数据和控制数据的注入

page组件:包装controller组件,指定controller的参数(如加载数据的api等),在页面中布局定位

util:包括service以及其他的与业务逻辑无关的模块

main.js 定义了modules对象作为一个全局变量,然后将定义的所有的其它变量接在modules上面。将display放到modules.dipslay中,将controller放到modules.controller,以此类推

由于React的JSX的格式需要babel –presets = react 进行转换,并且不希望在浏览器中导入browser.js 让客户端浏览器转换,所以要用npm install babel 与 npm install babel-preset-react,以及npm install gulp-babel,然后在gulpfile.js中定义自动脚本转换任务(关于脚本打包在后面一块儿说)

上述的display组件由父元素设置属性来传递数据,自己只有渲染数据的功能,父元素也可以为display组件提供一些方法,如对于一个Form组件,封装了Form的样式和数据接口,父元素controller中的render函数中渲染
<Form submitHanlder={this.submit}/>
,为Form提供一个submit的方法。

上述controller组件主要的功能就是维护整个组件的数据模型的状态,并且用数据模型来渲染。这个也是React的特点,M —> V单向数据流。对与数据的获取,我才用$.ajax的方法从服务器获取json格式的数据。

最后page组件就很简单,

//Page_Index.js
var Page_Index = React.createClass({
render:function(){
return (
<div>
<Navigator />
<Controller_A />
</div>
)
}
})
//index.html
<script type="text/javascript">
//这个代码不需要Babel的转换,其它的JSX在服务端转换好,用户可以直接使用了,不需要浏览器端再browser.js动态转换
ReactDOM.render(React.createElement(modules.Page_Index, null), document.getElementById('content'));
</script>


脚本打包

var gulp = require('gulp');
//concat用于将其它js文件合并到一个文件中
//由于使用了modules对象,不存在变量名污染的问题
var concat = require('gulp-concat');
//将JSX转换成正常的js
var babel = require('gulp-babel');
//丑化js(压缩js文件成min.js)
var uglify = require('gulp-uglify');
var config = {
scripts:['components/src/main.js','components/src/modules/**/*.js','components/src/util/*.js'],
styles_sass:['public/sass/**/*.scss']
}

gulp.task('react-script',function(){
return gulp.src(config.scripts)
.pipe(concat("components.min.js"))
.pipe(babel({
presets:['react']
}))
.pipe(uglify())
.pipe(gulp.dest('./components/build'))
});
//自动编译
gulp.task('watch',function(){
gulp.watch(config.scripts,['react-script']);
})
gulp.task('default',['watch'],function(){})


总结

详细的技术我不会在这里说,网上太多的技术资料了。前端技术还年轻,有太多的可能性等你发觉。总的来说,做出来后,维护非常的方便,添加新组件,修改旧组件,不会对其它部分有任何影响。这样下来,终于摆脱了之前做前端的时候各种混乱的局面了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: