webpack+react+es6开发模式
一、前言
实习了两个月,把在公司用到的前端开发模式做个简单的整理。公司里前端开发模式webpack+react+redux+es6,这里去掉了redux。
webpack, react, redux等学习网址:http://www.cnblogs.com/hujunzheng/p/5405780.html
二、简单的步骤条组件
1、通过react自定义的组件进行模拟
注:只是用了react,用到相关react的js请到 https://github.com/hjzgg/webpack-react 下的build文件夹下载。
html如下:
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="step.css"> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> var Line = React.createClass({ render: function() { let self = this; let active = this.props.active; let value = 0;//进度条没有加载 if(active == 1) {//进度条加载完成 value = 100; } return ( <div className="ant-progress-line"> <div> <div className="ant-progress-outer"> <div className="ant-progress-inner"> <div style={{width: value+"%"}} className="ant-progress-bg"> </div> </div> </div> </div> </div> ); } }); var Circle = React.createClass({ render: function(){ let content = this.props.content; let number = this.props.number; let active = this.props.active; let self = this; return ( <div className="ant-steps-head"> <div className="ant-steps-head-inner" style={active ? {backgroundColor: "#2db7f5"} : {backgroundColor: "#c1c1c1"}} onClick={function(){self.props.preStep(number)}}> <span className="ant-steps-icon"> {number+1} </span> </div> <div className="ant-steps-text" style={active ? {color: "#2db7f5"} : {color: "#c1c1c1"}}> {content} </div> </div> ); } }); var Step = React.createClass({ getInitialState: function() { return { curStep: 0,//当前正操作哪一步 maxStep: 0,//执行最远的一步 }; }, nextStep: function(){ let self = this; let curStep = this.state.curStep; let maxStep = this.state.maxStep; this.setState({ curStep: curStep+1, maxStep: maxStep <= curStep ? curStep+1 : maxStep, }); }, preStep: function(toStep){ let maxStep = this.state.maxStep; let curStep = this.state.curStep; if(toStep > maxStep || toStep == curStep) return; this.setState({ curStep: toStep, }); if(this.props.mainPreStep) this.props.mainPreStep(toStep); }, render: function(){ let self = this; let contents = self.props.contents; let steps = contents.map(function(content, index){ let activeCircle = true; let activeLine = false; if(self.state.curStep > 0 && self.state.curStep-1 >= index) activeLine = true; if(index > self.state.curStep) activeCircle = false; if(index == contents.length-1) { if(index == 0) { return ( <div className="step-main-div"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> </div> ); } else { return ( <div className="step-main-div step-main-div-move"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> </div> ); } } else if(index == 0) { return ( <div className="step-main-div"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> <Line active={activeLine}/> </div> ); } else { return ( <div className="step-main-div step-main-div-move"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> <Line active={activeLine}/> </div> ); } }); return ( <div style={{width: "100%"}}> { steps } </div> ); } }); var MainDiv = React.createClass({ nextStep: function(){ this.refs.myStep.nextStep(); }, render: function(){ return ( <div> <div style={{marginTop: "100px", width: "70%", display: "inline-block"}}> <Step contents={["first", "second", "third", "forth"]} ref="myStep"/> </div> <div style={{display: "inline"}}> <a href="javascript:void(0)" onClick={this.nextStep}>next</a> </div> </div> ); } }); ReactDOM.render( <MainDiv />, document.getElementById('example') ); </script> </body> </html>
css如下:
.ant-steps-head { width: 200px; position: relative; display: inline-block; vertical-align: top; text-align: center; } .ant-steps-text{ width: 200px; font-size: 16px; } .ant-steps-head-inner { margin: auto; border-color: #2db7f5; display: block; border: 1px solid #ccc; cursor: pointer; width: 40px; height: 40px; line-height: 40px; border-radius: 40px; font-size: 18px; -webkit-transition: background-color .3s ease,border-color .3s ease; transition: background-color .3s ease,border-color .3s ease; } .ant-steps-icon { color: #fff; line-height: 1; top: -1.5px; position: relative; } .ant-progress-line { width: 235px; margin-left: -75px; line-height: 40px; position: relative; display: inline-block; } .ant-progress-outer { padding-right: 45px; margin-right: -45px; display: inline-block; width: 100%; } .ant-progress-inner { display: inline-block; width: 100%; background-color: #c1c1c1; border-radius: 100px; vertical-align: middle; } .ant-progress-bg { border-radius: 100px; height: 4px; background-color: #2db7f5; -webkit-transition: all .3s linear 0s; transition: all .3s linear 0s; position: relative; } .step-main-div{ display:inline; width: 315px; } .step-main-div-move{ margin-left: -120px; }
2、通过webpack+react+es6进行模拟
注:可以fork我的github https://github.com/hjzgg/webpack-react/tree/master/webpackAndReact ,当然可以从0开始...
(1)、首先为项目建立一个名字,例如“webpack+react”, 建立src/step、src/css和build目录,在项目根目录下建立package.json文件,内容如下:
{ "name": "react-webpack", "version": "1.0.0", "description": "webpack demo", "main": "index.js", "scripts": { "start": "node server.js", "dev": "webpack-dev-server --port 8000 --devtool eval --progress --colors --hot --inline", "build-before": "webpack --display-error-details --progress --colors -p", "build": "webpack --config webpack.build.config.js --display-error-details --progress --colors", "build-watch": "webpack --display-error-details --progress --colors --watch --debug --devtool source-map --output-pathinfo", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "react", "webpack" ], "author": "hjzgg", "devDependencies": { "babel-core": "^6.3.21", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "css-loader": "~0.16.0", "style-loader": "~0.12.3", "react": "^0.14.3", "react-hot-loader": "^1.3.0", "react-router": "^1.0.2", "extract-text-webpack-plugin": "^0.8.2", "webpack": "^1.12.9", "webpack-dev-server": "^1.14.0" }, "dependencies": { "lodash": "^3.9.3", "react": "^0.14.3", "react-dom": "^0.14.3" } }
(2)、第二步就是创建我们webpack的配置文件webpack.config.js
var webpack = require('webpack'); module.exports = { entry: [ 'webpack/hot/only-dev-server', "./src/step/app.js" ], output: { path: './build', filename: 'bundle.js' }, module: { loaders: [ {test: /\.js?$/, exclude: /node_modules/, loaders: ['react-hot','babel-loader?presets[]=react,presets[]=es2015'] }, { test: /\.css$/, loader: 'style!css'} ] }, resolve:{ extensions:['','.js','.json'] }, plugins: [ new webpack.NoErrorsPlugin() ] };
(3)、入口文件 index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>New React App</title> <!<link rel="stylesheet" type="text/css" href="src/css/main.css"> --> <!-- <link rel="stylesheet" type="text/css" href="src/css/step.css"> --> </head> <body> <script src="bundle.js"></script> </body> </html>
注意,这里面引用的bundle.js文件非常重要,它是我们打包后的入口文件,不引入它程序是跑不起来的。
(4)、程序的入口文件src/step/app.js,在这里加载了我们自定义的步骤条组件
import React from 'react'; import ReactDOM from 'react-dom'; import MainDiv from './mainDiv'; ReactDOM.render ( <MainDiv />, document.body );
(5)、src/step/app.js中引用的src/step/mainDiv.js
import React from 'react'; import Step from './Step'; export default class MainDiv extends React.Component{ constructor(props){ super(props); this.nextStep = this.nextStep.bind(this); } nextStep(){ this.refs.myStep.nextStep(); } render(){ return ( <div> <div style={{marginTop: "100px", width: "70%", display: "inline-block"}}> <Step contents={["first", "second", "third", "forth"]} ref="myStep"/> </div> <div style={{display: "inline"}}> <a href="javascript:void(0)" onClick={this.nextStep}>next</a> </div> </div> ); } }
(6)、src/step/mainDiv.js中引用的src/step/Step.jsp (自定的步骤条组件)
import React from 'react'; import '../css/step.css'; class Line extends React.Component{ constructor(props){ super(props); } render(){ let self = this; let active = this.props.active; let value = 0;//进度条没有加载 if(active == 1) {//进度条加载完成 value = 100; } return( <div className="ant-progress-line"> <div> <div className="ant-progress-outer"> <div className="ant-progress-inner"> <div style={{width: value+"%"}} className="ant-progress-bg"> </div> </div> </div> </div> </div> ); } } class Circle extends React.Component{ constructor(props){ super(props); } render(){ let content = this.props.content; let number = this.props.number; let active = this.props.active; let self = this; return ( <div className="ant-steps-head"> <div className="ant-steps-head-inner" style={active ? {backgroundColor: "#2db7f5"} : {backgroundColor: "#c1c1c1"}} onClick={function(){self.props.preStep(number)}}> <span className="ant-steps-icon"> {number+1} </span> </div> <div className="ant-steps-text" style={active ? {color: "#2db7f5"} : {color: "#c1c1c1"}}> {content} </div> </div> ); } } class Step extends React.Component { constructor(props) { super(props); this.state = { curStep: 0,//当前正操作哪一步 maxStep: 0,//执行最远的一步 }; this.nextStep = this.nextStep.bind(this); this.preStep = this.preStep.bind(this); } nextStep(){ let self = this; let curStep = this.state.curStep; let maxStep = this.state.maxStep; this.setState({ curStep: curStep+1, maxStep: maxStep <= curStep ? curStep+1 : maxStep, }); } preStep(toStep){ let maxStep = this.state.maxStep; let curStep = this.state.curStep; if(toStep > maxStep || toStep == curStep) return; this.setState({ curStep: toStep, }); if(this.props.mainPreStep) this.props.mainPreStep(toStep); } render(){ let self = this; let contents = self.props.contents; let steps = contents.map(function(content, index){ let activeCircle = true; let activeLine = false; if(self.state.curStep > 0 && self.state.curStep-1 >= index) activeLine = true; if(index > self.state.curStep) activeCircle = false; if(index == contents.length-1) { if(index == 0) { return ( <div className="step-main-div"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> </div> ); } else { return ( <div className="step-main-div step-main-div-move"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> </div> ); } } else if(index == 0) { return ( <div className="step-main-div"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> <Line active={activeLine}/> </div> ); } else { return ( <div className="step-main-div step-main-div-move"> <Circle active={activeCircle} content={content} number={index} preStep={self.preStep}/> <Line active={activeLine}/> </div> ); } }); return ( <div style={{width: "100%"}}> { steps } </div> ); } } module.exports = Step;
(7)、src/css/step.css (组件样式)
.ant-steps-head { width: 200px; position: relative; display: inline-block; vertical-align: top; text-align: center; } .ant-steps-text{ width: 200px; font-size: 16px; } .ant-steps-head-inner { margin: auto; border-color: #2db7f5; display: block; border: 1px solid #ccc; cursor: pointer; width: 40px; height: 40px; line-height: 40px; border-radius: 40px; font-size: 18px; -webkit-transition: background-color .3s ease,border-color .3s ease; transition: background-color .3s ease,border-color .3s ease; } .ant-steps-icon { color: #fff; line-height: 1; top: -1.5px; position: relative; } .ant-progress-line { width: 235px; margin-left: -75px; line-height: 40px; position: relative; display: inline-block; } .ant-progress-outer { padding-right: 45px; margin-right: -45px; display: inline-block; width: 100%; } .ant-progress-inner { display: inline-block; width: 100%; background-color: #c1c1c1; border-radius: 100px; vertical-align: middle; } .ant-progress-bg { border-radius: 100px; height: 4px; background-color: #2db7f5; -webkit-transition: all .3s linear 0s; transition: all .3s linear 0s; position: relative; } .step-main-div{ display:inline; width: 315px; } .step-main-div-move{ margin-left: -120px; }
(8)、在项目根目录下,打开bash,执行npm install, 等待执行完毕,项目的根目录下会多出node_modules文件夹,这是项目所需要的一些依赖文件。
(9)、最后npm run dev,将项目跑起来...
3、css-loader和style-loader
webpack可以很方便的帮助我们导入css文件,需要我们下载css的loader,然后在webpack.config.js中配置(这里已经配置好了)。然后在js文件直接import 'xxx.css'就可以直接使用css样式了。
引用css的另一个办法就是在入口文件index.html中通过<link .../>来实现,也可以达到目的。当然还是推荐前者。
4、配置问题
关于工程依赖,工程启动,es6解析等一些配置,还是要好好研究一下package.json和webpack.config.js这两个文件了,请看看下面的文章:
http://www.cnblogs.com/skylar/p/React-Webpack-ES6.html
三、demo下载
本文来自博客园,作者:hjzqyx,转载请注明原文链接:https://www.cnblogs.com/hujunzheng/p/5538293.html