0ETai9rvBxlRQi9T.png

最近构思了一个练手项目,应用react实现程序的逻辑,从而进一步学习React框架开发。这次的例子是一个纯前端的简单应用,模拟实现图片上传和展示功能。应用中,使用sessionStorage存储图片数据,并且将sessionStorage中存储的图片数据,以列表的形式展示出来。

svtnhYqBWui2IiFG.png

目录结构

用Webpack打包React应用

Webpack 是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能。之前的例子中,对react的模块化,采用的是requirejs的AMD方式,使用Webpack之后,我们就可以使用nodejs的commonjs方式编写模块化的js代码。通过webpack,会将所有依赖的资源打包成一个单独的bundle,包含应用的逻辑代码,还有依赖的模块。

如果使用jsx格式编写混编的js和html代码,还需要安装相应的loader,才能成功打包,使用的是babel-loader。这里的loader除了jsx之外,根据需要,还可以支持sass等其他格式。

安装相应的npm依赖包

npm install react --save-dev
npm install react-dom --save-dev
npm install webpack --save-dev
npm install babel-loader --save-dev

跟所有的应用程序一样,react也需要有一个入口点,webpack会从入口点开始,对所有的依赖文件进行打包,在webpack.config.js配置文件中,进行相应的配置;entry就是入口点

module.exports = {
    entry:[
        './app/main.js'
    ],
    output: {
        path: __dirname + '/assets/',
        publicPath: "/assets/",
        filename: '[name].bundle.js'
    },
    resolve:{},
    module: {
        loaders: [
            /*{
                test: /\.scss$/,
                loaders: ["style", "css", "sass"]
            },*/{
                test: /\.js$/,
                loaders: ['babel-loader'],
                include: __dirname + '/app/'
            },
            { test: /\.jsx?$/, loaders: ['babel','jsx?harmony']}
        ]
    },
    plugins:[]
};

使用Gulp构建项目

为了开发和调试方便,引入构建工具gulp,主要使用到的插件包括:gulp-connectgulp-sassgulp-webpackgulp-uglify。分别使用npm安装对应的模块,npm install gulp --save-dev

项目开发中,简单的实现了几个Task,进行项目打包和构建。

var connect = require('gulp-connect');
var gulpWebpack = require('gulp-webpack');
var bower = require('gulp-bower');
var uglify = require('gulp-uglify');
var sass = require('gulp-sass');
var webpackConfig = require('./webpack.config');
gulp.task('bower', function() {
    return bower('./bower_components')
        .pipe(gulp.dest('./static/lib/'));
});
gulp.task('easy_webpack',function(){
    gulp.src('./app/main.js')
        .pipe(gulpWebpack(webpackConfig))
        .pipe(uglify())
        .pipe(gulp.dest('./assets/scripts/'))
});
gulp.task('easy_sass', function () {
    return gulp.src(path.SASS + '/**/*.scss')
        .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest('./assets/styles/'));
});
gulp.task('easy_build',['bower','easy_webpack','easy_sass'], function () {});
gulp.task('staticserver', function() {
    connect.server({
        port:3333,
    });
});

React的组件

搭建好环境之后,react的使用非常方便,把html根据需要拆分成不同的模块就可以直接在jsx语法的代码中混合编写,ReactDom.render就可以把模版转换成html代码,并且把html模块代码嵌入到指定的dom对象中,<代表往后是html代码,当作html解析,{代笔往后是js代码,当作js解析,需要注意的是,因为class是关键字,所以需要把class替换成className,把for替换成htmlFor。

var React = require('react');
var ReactDOM = require('react-dom');
module.exports = React.createClass({
    handleClick:function(event){
        console.log(event.target);
    },
    render: function() {
        return (
            <div className="img-item">
                <div className="img-view" onClick="{this.handleClick}">
                    <img className="picture" src={this.props.imgData.file}/>
                </div>
                <div className="img-info">
                    <span className="img-name">{this.props.imgData.name}</span>
                    <span className="img-type">{this.props.imgData.format}</span>
                </div>
            </div>
        );
    }
});
......
#使用的示例
var imageCtrl = new ImageCtrl();
var imageDataStore = imageCtrl.findAll();
ReactDOM.render(
    <div className="img-content card-mode">
        <ul className="js-img-list u-clearfix">
            {
                imageDataStore.map(function (item,index) {
                    return <li key={item.id}><ImgListItemComponent imgData={item}/></li>
                })
            }
        </ul>
    </div>,
    document.getElementById('imageList')
);

在React中,通过React.createClass方法就可以生成一个组件,通过这个方法,我们可以封装自己的组件,并且像普通的html标签一样在网页中插入。界面交互的大多数场景实现,就是在组织不同的组件,实现组件的复用和状态控制。对于组件,我们可以像普通的html标签一样,设置属性,然后通过this.props就可以读取对应的属性,不同于html标签的是,jsx的属性,支持所有js的数据类型而不是普通字符串。

React组件的props可以通过定义变量的方式,在组建类的外部访问,var imgList = <ImgListItemComponent imgData={item}/>,然后读取imgList.props.imgData,但是官方建议不要在外部对props进行修改,因为这个是不可控的。

React创新性的将组件看成是一个状态机,页面渲染的时候,根据state属性的初始状态来决定如何渲染,在组件有互动需要的时候,不同的交互会导致state的改变,从而触发重新渲染UI。这样的实现机制和Jquery的事件绑定机制,设计理念是完全不一样的。其中getInitialState返回的object会被赋值作为初始化的state。在交互过程中,如果有需要改变状态的时候,执行this.setState({fileContent:"",fileStatus:false,fileEntity:null});,在传入的对象中,制定的state对应的值就会改变,从而导致render中根据对应的state值来渲染。

......
module.exports = React.createClass({
    getInitialState: function() {
        return {fileTip: "",fileName: "",fileStatus:false,fileEntity:null,clicked: false,fileContent:"",fileNameShow:""};
    },
    render:function(){
        if (this.state.clicked) {
            return (
                <div className="simple-modal upload-modal">
            ...省略...
                </div>
            );
        }else {
            return <div />;
        }
    }
.......

this.props和this.state都是组件类提供的属性,可以通过组件直接读取,他们的区别是,props是固定的属性,已经设定就不再变化,而state根据交互的需要会发生变化。

React 使用驼峰命名规范的方式给组件绑定事件处理器。如果需要绑定点击事件,直接设置onClick就可以,onClick="{this.handleClick}"绑定成功,如果用户点击onClick就会调用React.createClass创建的对象中的handleClick函数,结合setState就可以动态的改变组件的状态,进而更新界面。

开发这个应用的过程中,使用了mixin实现的弹窗组件,该组件通过在body的最后面添加一个div标签来实现弹窗;基本够用,接下来的学习中,还会深入的学习mixin和弹窗的实现。khan学院的React modal

开发过程

在开发的过程中,因为最终要将html代码拆分成不同的模块,实现整个功能的过程中,可能涉及多个场景,所以将不同的场景,分别以纯静态页面的方式实现,这样就可以快速的调整页面布局,拆分之后保留页面原型。

保存图片的时候,存储格式是ImageData类,该类扮演了Schema的作用;图片通过File读取之后,以base64形式保存在sessionStorage中,保存的过程抽象成专门的模块,这样以后需要实现异步上传的时候,可以直接重新实现该模块。该模块使用mocha进行单元测试。

/*图片存储数据结构Schema*/
ImageData = function(initData){
    this.name = "";
    this.id = "";
    this.desc = "";
    this.url = "";
    this.visit = "";
    this.createTime = null;
    this.format = null;
    this.file = "";
    this.type = "";
    var dataTypeList = ImageData.getParamList();
    if(typeof initData == "object"){
        for(var key in dataTypeList){
            var keyName = dataTypeList[key];
            if(initData[keyName]){
                this[keyName] = initData[keyName];
            }
        }
    }
};
ImageData.getParamList = function(){
    var dataTypeList = ["name","id","desc","url","visit","createTime","format","file","type"];
    return dataTypeList;
};
/*数据存储相关代码*/
var DataHandler = {
    get:function(key,callback){
        if(typeof sessionStorage != "object"){
            return [];
        }
        var dataStr = sessionStorage.getItem(key);
        var keyData = [];
        if(dataStr){
            keyData = JSON.parse(dataStr);
        }
        typeof callback == "function" && callback(keyData);
        return keyData;
    },
    //以下代码省略
    ......

预览地址:http://pages.liuwill.com/
项目代码:https://github.com/liuwill/react-webpack-startup

下载源代码之后,执行npm install安装需要的依赖包,然后按照顺序执行gulp任务,就可以启动静态服务器预览效果。

你可能感兴趣的内容
React入门学习实例 收藏,2746 浏览
React 入门教程 收藏,2574 浏览
0条评论
YE

yegor256

这家伙太懒了,什么都没留下
Owner