1、package.json:
{ "name": "wtest", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node server.js", "build": "NODE_ENV=production&&npm run output", "output": "webpack --config webpack.build.js", "test": "node ./dist/test.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "autoprefixer-loader": "^3.2.0", "babel-core": "^6.23.1", "babel-loader": "^6.3.2", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-preset-es2015": "^6.22.0", "babel-preset-es2016": "^6.22.0", "babel-preset-es2017": "^6.22.0", "babel-preset-react": "^6.23.0", "babel-preset-stage-0": "^6.22.0", "copy-webpack-plugin": "^4.0.1", "css-loader": "^0.26.2", "extract-text-webpack-plugin": "^2.0.0", "file-loader": "^0.10.1", "html-webpack-plugin": "^2.28.0", "mobx": "^3.1.2", "mobx-react": "^4.1.1", "node-sass": "^4.5.0", "react": "^15.4.2", "react-dom": "^15.4.2", "react-hot-loader": "^1.3.1", "react-router": "^3.0.2", "reload": "^1.1.1", "sass-loader": "^6.0.2", "style-loader": "^0.13.2", "uglifyjs-webpack-plugin": "^0.3.0", "webpack": "^2.2.1", "webpack-del-plugin": "^0.0.1", "webpack-dev-middleware": "^1.10.1", "webpack-dev-server": "^2.4.1", "webpack-hot-middleware": "^2.17.1", "webpack-spritesmith": "^0.3.1", "webpack-uglify-js-plugin": "^1.1.9" } }
2、webpack:
const webpack = require('webpack'); const webpackUglifyJsPlugin = require('webpack-uglify-js-plugin'); const path = require('path'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const config = { entry: [ "webpack-hot-middleware/client?reload=true", // 这里是你的入口文件 "./index.js", ], output: { //输出目录 publicPath: "", path: __dirname, filename: 'bundle.js', }, module: { rules: [{ test: /\.jsx?$/, use: ['react-hot-loader', { loader: 'babel-loader', options: { presets: ['es2015', 'es2016', 'es2017', 'stage-0', 'react'], //babel presets ,首先需要react解析react然后再es语法编译成js plugins: ['transform-decorators-legacy'] } }], exclude: /node_modules/ }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", loader: "css-loader!autoprefixer-loader?{browsers:['last 6 Chrome versions', 'last 3 Safari versions', 'iOS >= 5', 'Android >= 4.0']}!sass-loader", }), }, { test: /\.png$/, use: { loader: 'file-loader', options: { name: '../img/[name].[ext]' } } }] }, plugins: [ new webpack.optimize.OccurrenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), //热编译开启 new webpack.NoEmitOnErrorsPlugin(), new ExtractTextPlugin('css/style.css') /*new HtmlWebpackPlugin({ title: 'index', hash:true, template: 'index.ejs', // Load a custom template (ejs by default see the FAQ for details) })*/ ] }; module.exports = config;
3、server.js:
var webpack = require('webpack'), webpackDevMiddleware = require('webpack-dev-middleware'), webpackHotMiddleware = require('webpack-hot-middleware'), config = require("./webpack.start.js"), express = require('express'), app = express(), compiler = webpack(config); app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath, noInfo: true, stats: { colors: true, progress: true } })); app.use(webpackHotMiddleware(compiler, { //中间件实现热刷新 noInfo: true, publicPath: config.output.publicPath })); app.get('*', function(req, res) { var fileName = req.url; console.log(fileName); if (fileName == '/') { res.sendFile(__dirname + '/index.html'); }else{ res.sendFile(__dirname + fileName); } }); app.listen(8087,'0.0.0.0'); //node 构建server
3、store:
import { observer } from "mobx-react"; import { observable, action, computed ,autorun} from "mobx"; export default class NewStore { @observable inputValue1; //注册监听的数据 @observable inputValue2; @observable childValue; constructor() { this.inputValue1=0; this.inputValue2=0;//初始化数据的值 this.fullValue=0; this.childValue=0; } @action changeValue(s,e){ //当促发action的时候,改变对应的数据 let tar=e.currentTarget; let val=Math.abs(tar.value); if(tar.name=='val1'){ this.inputValue1=val; }else if(tar.name=='val2'){ this.inputValue2=val; } } @computed get sum(){ //computed 是自动监听登记的数据,如果对应数据有改变就自动执行该函数,然后返回数据给接收的接口 this.fullValue=this.inputValue1+this.inputValue2; console.log(this.fullValue) return this.fullValue; } @action childEvent(){ this.childValue=this.childValue+3; } }
import TestStore from './test.js'; import NextStore from "./next.js"; import NewStore from "./new.js"; import FormStore from "./form.js"; import MenuStore from "./menu.js"; import NumChange from "./comm/numChange.js" export default { testStore:new TestStore(), nextStore:new NextStore(), newStore:new NewStore(), formStore:new FormStore(), menuStore:new MenuStore(), numChange:new NumChange() }
4、index.js:
import "./js/auto_rem.js"; import "./css/style.scss"; import React from "react"; import { render } from "react-dom"; import { observable, computed, autorun } from "mobx"; import { Provider } from 'mobx-react'; import { Router, Route, hashHistory ,browserHistory} from 'react-router'; import Test from "./src/components/test.js"; import Next from "./src/components/next.js"; import New from "./src/components/new.js"; import Forms from "./src/components/form.js"; import Menu from "./src/components/menu.js"; import store from "./src/store/store.js"; const routes = ( <Route component={App}> <Route path="/" component={Menu}/> <Route path="/menu" component={Menu}/> <Route path="/form" component={Forms}/> <Route path="/new" component={New}/> <Route path="/test" component={Test}/> <Route path="/next" component={Next}/> </Route> ); class App extends React.Component { render() { return ( <Provider {...store}> //注入所有的store <Router history={hashHistory} > {routes} </Router> </Provider> ) } } render( < App />, document.getElementById('app'));
4、view:
import {observer,inject} from "mobx-react"; import {observable,action,computed,autorun} from "mobx"; import React,{Component} from "react"; import {render} from "react-dom"; import Child from "./comm/child.js"; @inject(['newStore']) @observer //引入需要的store,然后组件就可以在props中访问 export default class New extends Component{ constructor(props) { super(props); this.store=this.props.newStore; //访问注入的store this.changeValue=this.store.changeValue.bind(this.store,event) //访问mobx中的事件,store中的事件 } render(){ return( <div> <input type='tel' name='val1' onKeyUp={this.changeValue}/>+ <input type='tel' name='val2' onKeyUp={this.changeValue}/>= <span>{this.store.sum}</span> <Child/> </div> ) } }
前端工程师、程序员