scss + react + webpack + es6
写在前面:
刚学习完慕课网里的一个幻灯片案例,自己加了刚学的react,两者结合。首先让大家看看效果 点击此处
你可以先用纯js实现上面的效果:我的github上的 JS代码 或者 观看慕课提供的课程。再趁热打铁加上react
React分析
JS实现
对于js来说,下面按钮一点击,就能根据当前的索引为按钮和图片绑定对应好的样式:取到对应的DOM元素,加上定义好的样式名,就能实现绑定效果。
React实现
但对于React来说,组件化开发的思想,可不是取得DOM元素就了事,因为React设计的初衷就是为了摆脱DOM。
那对于这个Demo,如何实现点击按钮,上面的图片对应着变化呢?
这个Demo拆成两个组件,一个图片组件,一个按钮。两个组件共用一个属性库,这就解决问题了。只要属性库的值变化,两个组件就都跟着变化。
首先看一下目录结构
//---css 样式文件 //---data //----imgDatas.json 存放图片信息json文件 //---imgs 图片存放 //---App.jsx //---index.html //---main.js //---package.json //---webpack.config.js
接下来定义一下webpack.config.js
var OpenBrowserPlugin = require('open-browser-webpack-plugin'); //自动打开浏览器 var config={ entry:'./main.js', //入口文件 output:{ path:'./', //输出路径 filename:'index.js' //输出文件 }, plugins: [ new OpenBrowserPlugin({ //自动打开浏览器 url: 'http://localhost:8080' }) ], module:{ loaders:[{ test:/.jsx?$/, //正则匹配 js 文件变化 exclude:/node_modules/, loader:'babel', query:{ presets:['es2015','react'] //将es6与react变成现代浏览器能看懂的语言 } },{ test:'/.(png|jpg|woff|woff2)$/', loader:'url-loader?limit=8192' //自动将低于8192bit的图片变成base64 },{ test:/.json$/, loader:'json-loader' //加载json文件 }] } }; module.exports = config;
再看一下 package.json文件的内容
... "scripts": { "start": "webpack-dev-server" }, ... "dependencies": { "babel-core": "^6.10.4", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.9.0", "babel-preset-react": "^6.11.1", "json-loader": "^0.5.4", "open-browser-webpack-plugin": "0.0.2", "react": "^15.2.0", "react-dom": "^15.2.0" }
接下来看一下main.js 文件的内容
import React from 'react'; import ReactDOM from 'react-dom'; import Slider from './App.jsx'; //引入APP.jsx ReactDOM.render( <Slider/>, document.getElementById('example') );
最重要的内容是APP.jsx 接下来一起学习重头戏
思路:
1.拆分按钮 templateCtrl 和图片templateMain 组件
return ( <div className="slider"> <div className="main"> {templateMain} </div> <div className="ctrl"> {templateCtrl} </div> </div> );
2.设置getInitialState imgsArrangeArr:[]
getInitialState : function(){ return{ imgsArrangeArr : [] }; },
3.根据图片数据foreach设置templateCtrl templateMain 的props数据,并初始化各自组件中间状态值isCenter为false
ImgDatas.forEach(function(value , index){ if (!this.state.imgsArrangeArr[index]) { this.state.imgsArrangeArr[index] = { isCenter : false }; } templateMain.push( <TemplateMainI data={value} center={this.center(index)} arrange={this.state.imgsArrangeArr[index]} right={index % 2? true : false} /> ); templateCtrl.push( <TemplateCtrlI data={value.img} center={this.center(index)} arrange={this.state.imgsArrangeArr[index]} /> ); }.bind(this));
4.渲染templateCtrl templateMain组件
var TemplateMainI = React.createClass({ render : function(){ var mainClassName = this.props.right?'main-i main-i_right':'main-i'; mainClassName += this.props.arrange.isCenter?' main-i_active':''; return( <div className={mainClassName}> <div className="caption"> <h2>{this.props.data.h1}</h2> <h3>{this.props.data.h2}</h3> </div> <img src={this.props.data.img} alt=""/> </div> ) } });
5.主方法:rearrange(centerIndex) 将选中值的isCenter设置为true,其余设置为false。
rearrange: function(centerIndex){ var imgsArrangeArr = this.state.imgsArrangeArr, imgsCenterArr = imgsArrangeArr.splice(centerIndex , 1); /*取出那组对应的数组*/ imgsCenterArr[0]={isCenter :true};/*把isCenter置为true*/ for(var i=0; i<imgsArrangeArr.length; i++){ imgsArrangeArr[i] = {isCenter : false} } imgsArrangeArr.splice(centerIndex, 0, imgsCenterArr[0]); /*将centerIndex的isCenter变成true*/ this.setState({ imgsArrangeArr:imgsArrangeArr }); },
接下来对比es6下的React
1、导入文件使用 import React from 'react'
2、var TemplateMainI = React.createClass({}) 写法变成定义一个类继承React的组件 class TemplateMainI extendsReact.Component{}
3、State
getInitialState : function(){ return{ imgsArrangeArr : [] }; },
在构造器中继承父类
es6语法
constructor(){ super(); this.state = { imgsArrangeArr : [] }; }
4、function XXX(){} 变成 es6 方法的写法 XXX(){}
5、onClick={this.handleClick} 需要绑定this onClick={this.handleClick.bind(this)}
其中还有很多变化需要细细研究 可以参考这篇文章
具体代码可以研究下我的github地址 Preview_silder,动手做一遍,收益良多。