├── .gitignore ├── reactERP ├── src │ ├── modules │ │ ├── login │ │ │ ├── Login.scss │ │ │ ├── LoginConstants.js │ │ │ ├── LoginAction.js │ │ │ ├── LoginReducer.js │ │ │ └── LoginComponent.js │ │ ├── cp │ │ │ ├── cp.css │ │ │ └── cp.js │ │ └── order │ │ │ ├── orderConstant.js │ │ │ ├── orderAction.js │ │ │ ├── orderReducer.js │ │ │ └── orderComponent.js │ ├── libs │ │ ├── bootstrap │ │ │ ├── css │ │ │ │ ├── bootstrap.global.css │ │ │ │ └── bootstrap-theme-light.css │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ └── datepicker │ │ │ │ ├── less │ │ │ │ └── datepicker.less │ │ │ │ └── css │ │ │ │ └── datepicker.css │ │ ├── common │ │ │ ├── global.scss │ │ │ ├── common.js │ │ │ └── common.scss │ │ ├── imgs │ │ │ ├── red.jpg │ │ │ ├── green.jpg │ │ │ └── yellow.jpg │ │ └── font-awesome │ │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ │ ├── less │ │ │ ├── fixed-width.less │ │ │ ├── larger.less │ │ │ ├── list.less │ │ │ ├── core.less │ │ │ ├── font-awesome.less │ │ │ ├── stacked.less │ │ │ ├── bordered-pulled.less │ │ │ ├── rotated-flipped.less │ │ │ ├── path.less │ │ │ ├── animated.less │ │ │ └── mixins.less │ │ │ └── scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _larger.scss │ │ │ ├── _list.scss │ │ │ ├── font-awesome.scss │ │ │ ├── _core.scss │ │ │ ├── _stacked.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _path.scss │ │ │ ├── _animated.scss │ │ │ └── _mixins.scss │ ├── components │ │ ├── cnode │ │ │ ├── cnode.scss │ │ │ └── cnode.js │ │ ├── datagrid │ │ │ ├── datagridconstants.js │ │ │ ├── datagridaction.js │ │ │ ├── datagridreducer.js │ │ │ └── datagridcomponent.js │ │ ├── app │ │ │ └── app.js │ │ ├── login │ │ │ ├── login.scss │ │ │ └── login.js │ │ ├── spinner │ │ │ ├── spinner.js │ │ │ └── spinner.scss │ │ ├── home │ │ │ ├── home.js │ │ │ ├── home.scss │ │ │ ├── header │ │ │ │ ├── header.scss │ │ │ │ └── header.js │ │ │ └── nav │ │ │ │ ├── nav.scss │ │ │ │ └── nav.js │ │ └── modal │ │ │ ├── modalcomponent.js │ │ │ └── modal.css │ ├── redux │ │ ├── rootReducer.js │ │ ├── configStore.js │ │ └── middleware.js │ ├── app.js │ ├── router │ │ └── index.js │ └── utils │ │ ├── ajaxMiddleware.js │ │ └── HttpClient.js ├── .DS_Store ├── dist │ ├── 46661d6d65debc63884004fed6e37e5c.svg │ ├── fonts │ │ ├── fontawesome-webfont.[md5.hash.hex:7].ttf │ │ └── fontawesome-webfont.[md5.hash.hex:7].woff │ └── src │ │ └── libs │ │ └── font-awesome │ │ └── fonts │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 ├── .babelrc ├── index.html ├── package.json └── webpack.config.js ├── redux ├── middleware │ ├── dist │ │ ├── 46661d6d65debc63884004fed6e37e5c.svg │ │ └── src │ │ │ └── libs │ │ │ └── font-awesome │ │ │ └── fonts │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ ├── .babelrc │ ├── src │ │ ├── components │ │ │ ├── datagrid │ │ │ │ ├── datagridconstants.js │ │ │ │ ├── datagridaction.js │ │ │ │ ├── datagridreducer.js │ │ │ │ └── datagridcomponent.js │ │ │ ├── cnode │ │ │ │ └── cnode.js │ │ │ └── spinner │ │ │ │ ├── spinner.js │ │ │ │ └── spinner.scss │ │ ├── redux │ │ │ ├── rootReducer.js │ │ │ ├── store.js │ │ │ └── middleware.js │ │ ├── app.js │ │ └── utils │ │ │ └── HttpClient.js │ ├── index.html │ ├── package.json │ ├── webpack.config.js │ └── README.md ├── README.md ├── combineReducers │ └── README.md └── connetProvider │ └── README.md ├── component └── src │ ├── app.es6.js │ ├── app.es5.js │ ├── define │ ├── define.es6.js │ ├── define.es5.js │ ├── define.html │ └── README.md │ ├── style │ └── README.md │ ├── event │ ├── event.html │ └── README.md │ ├── state │ ├── README.md │ └── state.html │ ├── render │ ├── condition-rendering.html │ └── README.md │ ├── form │ ├── input.html │ └── README.md │ ├── props │ └── props.html │ ├── lifecycle │ ├── lifecycle.html │ └── README.md │ └── communication │ ├── README.md │ └── communication.html ├── js └── react-dom.js ├── README.md ├── jsx ├── jsx.html └── README.md └── router ├── index.html ├── params.html └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /reactERP/node_modules/ 2 | -------------------------------------------------------------------------------- /reactERP/src/modules/login/Login.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /reactERP/src/libs/bootstrap/css/bootstrap.global.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /reactERP/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/.DS_Store -------------------------------------------------------------------------------- /reactERP/dist/46661d6d65debc63884004fed6e37e5c.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /reactERP/src/libs/common/global.scss: -------------------------------------------------------------------------------- 1 | $main-color: #1ab394; 2 | $main-color-hover: #19a085; 3 | -------------------------------------------------------------------------------- /redux/middleware/dist/46661d6d65debc63884004fed6e37e5c.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /reactERP/src/libs/imgs/red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/imgs/red.jpg -------------------------------------------------------------------------------- /reactERP/src/libs/imgs/green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/imgs/green.jpg -------------------------------------------------------------------------------- /reactERP/src/libs/imgs/yellow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/imgs/yellow.jpg -------------------------------------------------------------------------------- /reactERP/src/modules/cp/cp.css: -------------------------------------------------------------------------------- 1 | .c1{ 2 | color: red; 3 | width: 100%; 4 | height: 300px; 5 | border: solid 1px red; 6 | } -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /reactERP/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "modules": false }], 4 | "react", 5 | "latest", 6 | "stage-2" 7 | ] 8 | } 9 | 10 | -------------------------------------------------------------------------------- /reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].ttf -------------------------------------------------------------------------------- /reactERP/src/components/cnode/cnode.scss: -------------------------------------------------------------------------------- 1 | .dk-toolbar{ 2 | width: 100%; 3 | height: 50px; 4 | padding: 10px 20px; 5 | border-bottom: solid 1px #ccc; 6 | } -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].woff -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /redux/middleware/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "modules": false }], 4 | "react", 5 | "latest", 6 | "stage-2" 7 | ] 8 | } 9 | 10 | -------------------------------------------------------------------------------- /reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /reactERP/src/components/datagrid/datagridconstants.js: -------------------------------------------------------------------------------- 1 | export const Requesting = 'Requesting' 2 | export const Requested = 'Requested' 3 | export const RequestError = 'RequestError' -------------------------------------------------------------------------------- /reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /redux/middleware/src/components/datagrid/datagridconstants.js: -------------------------------------------------------------------------------- 1 | export const Requesting = 'Requesting' 2 | export const Requested = 'Requested' 3 | export const RequestError = 'RequestError' -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dk-lan/react/HEAD/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /reactERP/src/components/app/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class AppComponent extends React.Component{ 4 | render(){ 5 | return
{this.props.children}
6 | } 7 | } -------------------------------------------------------------------------------- /component/src/app.es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | //组件定义 5 | import DefineComponent from './define/define.es6'; 6 | ReactDOM.render(, document.getElementById('define')); -------------------------------------------------------------------------------- /reactERP/src/redux/rootReducer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {combineReducers} from 'redux' 3 | 4 | import datagrid from '../components/datagrid/datagridreducer' 5 | 6 | export default combineReducers({ 7 | datagrid 8 | }) -------------------------------------------------------------------------------- /redux/middleware/src/redux/rootReducer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {combineReducers} from 'redux' 3 | 4 | import datagrid from '../components/datagrid/datagridreducer' 5 | 6 | export default combineReducers({ 7 | datagrid 8 | }) -------------------------------------------------------------------------------- /component/src/app.es5.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | 4 | //组件定义 5 | var DefineComponent = require('./define/define.es5'); 6 | ReactDOM.render(, document.getElementById('define')); 7 | 8 | -------------------------------------------------------------------------------- /component/src/define/define.es6.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | class Component1 extends React.Component{ 3 | render(){ 4 | return ( 5 |
6 |

Tom

7 |

Sam

8 |
9 | ) 10 | } 11 | } 12 | export default Component1; -------------------------------------------------------------------------------- /reactERP/src/redux/configStore.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {createStore, applyMiddleware} from 'redux' 3 | 4 | import rootReducer from './rootReducer' 5 | 6 | import middleware from './middleware' 7 | 8 | const store = createStore(rootReducer, applyMiddleware(middleware)); 9 | 10 | export default store; -------------------------------------------------------------------------------- /component/src/define/define.es5.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var Component1 = React.createClass({ 3 | render: function(){ 4 | return ( 5 |
6 |

Tom

7 |

Sam

8 |
9 | ) 10 | } 11 | }) 12 | module.exports = Component1; -------------------------------------------------------------------------------- /redux/middleware/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {createStore, applyMiddleware} from 'redux' 3 | 4 | import rootReducer from './rootReducer' 5 | 6 | import middleware from './middleware' 7 | 8 | const store = createStore(rootReducer, applyMiddleware(middleware)); 9 | 10 | export default store; -------------------------------------------------------------------------------- /reactERP/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DK-React项目应用 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /redux/middleware/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DK-中间件实现案例 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /reactERP/src/libs/common/common.js: -------------------------------------------------------------------------------- 1 | import {EventEmitter} from 'events' 2 | 3 | export default { 4 | state: { 5 | component1: { 6 | count: 0 7 | }, 8 | component2: { 9 | count: 0 10 | } 11 | }, 12 | event: new EventEmitter(), 13 | addEvent(name, e){ 14 | this.event.on(name, e) 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /reactERP/src/modules/login/LoginConstants.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_LOGIN_REQUEST = 'LOGIN_LOGIN_REQUEST'; 2 | export const LOGIN_LOGIN_SUCCESS = 'LOGIN_LOGIN_SUCCESS'; 3 | export const LOGIN_LOGIN_FAIL = 'LOGIN_LOGIN_FAIL'; 4 | 5 | export const ORDER_GETCODE_REQUEST = 'ORDER_GETCODE_REQUEST'; 6 | export const ORDER_GETCODE_SUCCESS = 'ORDER_GETCODE_SUCCESS'; 7 | export const ORDER_GETCODE_FAIL = 'ORDER_GETCODE_FAIL'; -------------------------------------------------------------------------------- /reactERP/src/components/datagrid/datagridaction.js: -------------------------------------------------------------------------------- 1 | import * as constants from './datagridconstants' 2 | 3 | export function refresh(_config){ 4 | return { 5 | types: [constants.Requesting, constants.Requested, constants.RequestError], 6 | url: _config.url, 7 | method: _config.method || 'get', 8 | data: _config.data || {}, 9 | name: _config.name 10 | } 11 | } -------------------------------------------------------------------------------- /reactERP/src/modules/order/orderConstant.js: -------------------------------------------------------------------------------- 1 | export const ORDER_SCANCODE_REQUEST = 'ORDER_SCANCODE_REQUEST'; 2 | export const ORDER_SCANCODE_SUCCESS = 'ORDER_SCANCODE_SUCCESS'; 3 | export const ORDER_SCANCODE_FAIL = 'ORDER_SCANCODE_FAIL'; 4 | 5 | export const ORDER_PRINT_REQUEST = 'ORDER_SCANCODE_REQUEST'; 6 | export const ORDER_PRINT_SUCCESS = 'ORDER_SCANCODE_SUCCESS'; 7 | export const ORDER_PRINT_FAIL = 'ORDER_SCANCODE_FAIL'; -------------------------------------------------------------------------------- /redux/middleware/src/components/datagrid/datagridaction.js: -------------------------------------------------------------------------------- 1 | import * as constants from './datagridconstants' 2 | 3 | export function refresh(_config){ 4 | return { 5 | types: [constants.Requesting, constants.Requested, constants.RequestError], 6 | url: _config.url, 7 | method: _config.method || 'get', 8 | data: _config.data || {}, 9 | name: _config.name 10 | } 11 | } -------------------------------------------------------------------------------- /reactERP/src/modules/login/LoginAction.js: -------------------------------------------------------------------------------- 1 | import * as LoginConstants from './LoginConstants'; 2 | 3 | export function login(username, password){ 4 | return { 5 | types: ['a', 'b', 'c'], 6 | path: 'pro/fetchAllProducts', 7 | method: 'get', 8 | query: {username, password} 9 | } 10 | } 11 | 12 | export function getCode(){ 13 | return { 14 | types: ['getCode1', 'getCode2', 'getCode3'] 15 | } 16 | } -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /redux/middleware/src/app.js: -------------------------------------------------------------------------------- 1 | import './libs/bootstrap/css/bootstrap.min.css' 2 | import './libs/font-awesome/css/font-awesome.min.css' 3 | 4 | import React from 'react' 5 | import ReactDOM from 'react-dom' 6 | import {Provider} from 'react-redux' 7 | 8 | import store from './redux/configStore' 9 | import CNodeComponent from './components/cnode/cnode' 10 | 11 | ReactDOM.render( 12 | 13 | 14 | , 15 | document.getElementById('app') 16 | ) -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | -------------------------------------------------------------------------------- /reactERP/src/app.js: -------------------------------------------------------------------------------- 1 | import './libs/bootstrap/css/bootstrap.min.css' 2 | import './libs/font-awesome/css/font-awesome.min.css' 3 | import './libs/common/common.scss' 4 | 5 | import React from 'react' 6 | import ReactDOM from 'react-dom' 7 | import {Router, hashHistory} from 'react-router' 8 | import {Provider} from 'react-redux' 9 | 10 | import store from './redux/configStore' 11 | import routes from './router' 12 | 13 | ReactDOM.render( 14 | 15 | 16 | , 17 | document.getElementById('app') 18 | ) -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /redux/middleware/src/components/cnode/cnode.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Datagrid from '../../components/datagrid/datagridcomponent' 3 | 4 | export default class CNodeComponent extends React.Component{ 5 | static defaultProps = { 6 | config: { 7 | url: 'https://cnodejs.org/api/v1/topics', 8 | data: {page: 1, limit: 10}, 9 | cols: ['title', 'reply_count', 'top', 'create_at', 'last_reply_at'] 10 | } 11 | } 12 | render(){ 13 | return ( 14 |
15 | 16 |
17 | ) 18 | } 19 | } -------------------------------------------------------------------------------- /reactERP/src/modules/order/orderAction.js: -------------------------------------------------------------------------------- 1 | import * as orderConstant from './orderConstant' 2 | 3 | export function scanCode(){ 4 | return { 5 | types: [orderConstant.ORDER_SCANCODE_REQUEST, orderConstant.ORDER_PRINT_SUCCESS, orderConstant.ORDER_SCANCODE_FAIL], 6 | path: 'pro/fetchAllProducts', 7 | query: {code: '123'} 8 | } 9 | } 10 | 11 | export function print(){ 12 | return { 13 | type:[orderConstant.ORDER_PRINT_REQUEST, orderConstant.ORDER_PRINT_REQUEST, orderConstant.ORDER_PRINT_FAIL], 14 | path: 'http://10.3.134.78:81/print', 15 | method: 'post', 16 | query: {text: 'DK测试'} 17 | } 18 | } -------------------------------------------------------------------------------- /reactERP/src/modules/order/orderReducer.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import update from 'react-addons-update'; 3 | import * as OrderConstants from './orderConstant'; 4 | 5 | //[{name:'娃哈哈', price: 10.22}] 6 | function scanCode(state = [], action){ 7 | if(action.type == OrderConstants.ORDER_PRINT_SUCCESS){ 8 | const newState = update(state, {$push: [action.body]}); 9 | return newState; 10 | } 11 | return state; 12 | } 13 | 14 | function print(state = {}, action){ 15 | return state; 16 | } 17 | 18 | const orderReducers = combineReducers({ 19 | scanCode, 20 | print 21 | }); 22 | 23 | export default orderReducers; -------------------------------------------------------------------------------- /reactERP/src/components/login/login.scss: -------------------------------------------------------------------------------- 1 | .login-box{ 2 | width: 428px; 3 | height: 298px; 4 | position: absolute; 5 | left: 50%; 6 | top: 50%; 7 | transform: translate(-50%, -80%); 8 | background: #FFFFFF; 9 | border-radius: 5px; 10 | box-shadow: -30px 30px 50px rgba(0, 0, 0, 0.32); 11 | padding: 15px; 12 | border-top: solid 1px #efefef; 13 | border-right: solid 1px #efefef; 14 | .copyright{ 15 | font-size: 11px; 16 | margin: 0 auto; 17 | padding: 10px 10px 0; 18 | text-align: center; 19 | position: absolute; 20 | bottom: -32px; 21 | left: 50%; 22 | transform: translate(-50%, 0); 23 | color: #7F7F7F; 24 | } 25 | } -------------------------------------------------------------------------------- /reactERP/src/components/spinner/spinner.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import './spinner.scss' 3 | 4 | class SpinnerComponent extends React.Component{ 5 | render(){ 6 | let html = ( 7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ) 16 | return this.props.show ? html : null; 17 | } 18 | } 19 | 20 | export default SpinnerComponent -------------------------------------------------------------------------------- /redux/middleware/src/components/spinner/spinner.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import './spinner.scss' 3 | 4 | class SpinnerComponent extends React.Component{ 5 | render(){ 6 | let html = ( 7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ) 16 | return this.props.show ? html : null; 17 | } 18 | } 19 | 20 | export default SpinnerComponent -------------------------------------------------------------------------------- /reactERP/src/components/home/home.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import HeaderComponent from './header/header' 3 | import NavComponent from './nav/nav' 4 | import './home.scss' 5 | 6 | export default class HomeComponent extends Component{ 7 | render(){ 8 | return ( 9 |
10 | 11 |
12 | 13 |
14 |
{this.props.children}
15 |
16 |
17 |
@dk
18 |
19 | ) 20 | } 21 | } -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /reactERP/src/router/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Route, IndexRoute} from 'react-router' 3 | 4 | import AppComponent from '../components/app/app' 5 | import HomeComponent from '../components/home/home' 6 | import LoginComponent from '../components/login/login' 7 | import CNodeComponent from '../components/cnode/cnode' 8 | 9 | 10 | const routes = ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ) 20 | 21 | export default routes; -------------------------------------------------------------------------------- /reactERP/src/components/home/home.scss: -------------------------------------------------------------------------------- 1 | @import '../../libs/common/global.scss'; 2 | .dk-container{ 3 | width: 100%; 4 | height: 100%; 5 | position: relative; 6 | } 7 | 8 | 9 | 10 | .dk-body{position: fixed; top: 42px; left: 0; right: 0; bottom: 32px;} 11 | 12 | 13 | 14 | .dk-content{ 15 | position: absolute; top: 0; bottom: 0; left: 229px; right: 0; overflow: auto; 16 | .dk-toolbar{ 17 | width: 100%; 18 | height: 50px; 19 | padding: 10px 20px; 20 | border-bottom: solid 1px #ccc; 21 | } 22 | .dk-viewer{ 23 | width: 100%; 24 | position: absolute; 25 | top: 0; 26 | bottom: 0px; 27 | overflow-x: hidden; 28 | overflow-y: auto; 29 | } 30 | } 31 | 32 | .dk-footer{position: fixed; border-top: solid 1px #ccc; bottom: 0; height: 32px; width: 100%; text-align: center; line-height: 32px;} -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .@{fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /reactERP/src/components/datagrid/datagridreducer.js: -------------------------------------------------------------------------------- 1 | import * as constants from './datagridconstants' 2 | 3 | export default function datagrid(state = {}, action){ 4 | let _state = JSON.parse(JSON.stringify(state)); 5 | switch(action.type){ 6 | case constants.Requesting: 7 | _state.show = true; 8 | break; 9 | case constants.Requested: 10 | _state.show = false; 11 | if(action.name){ 12 | _state[action.name] = _state[action.name] || {}; 13 | _state[action.name].dataset = action.result; 14 | } else { 15 | _state.dataset = action.result; 16 | } 17 | break; 18 | case constants.RequestError: 19 | _state.show =false; 20 | _state.error = action.error; 21 | break 22 | } 23 | return _state; 24 | } -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /redux/middleware/src/components/datagrid/datagridreducer.js: -------------------------------------------------------------------------------- 1 | import * as constants from './datagridconstants' 2 | 3 | export default function datagrid(state = {}, action){ 4 | let _state = JSON.parse(JSON.stringify(state)); 5 | switch(action.type){ 6 | case constants.Requesting: 7 | _state.show = true; 8 | break; 9 | case constants.Requested: 10 | _state.show = false; 11 | if(action.name){ 12 | _state[action.name] = _state[action.name] || {}; 13 | _state[action.name].dataset = action.result; 14 | } else { 15 | _state.dataset = action.result; 16 | } 17 | break; 18 | case constants.RequestError: 19 | _state.show =false; 20 | _state.error = action.error; 21 | break 22 | } 23 | return _state; 24 | } -------------------------------------------------------------------------------- /reactERP/src/redux/middleware.js: -------------------------------------------------------------------------------- 1 | import http from '../utils/httpclient' 2 | import * as constants from '../components/datagrid/datagridconstants' 3 | 4 | export default function(api){ 5 | return function(dispatch){ 6 | return function(action){ 7 | let {type, types, url, data, method = 'get', name} = action; 8 | if(!url){ 9 | return dispatch(action) 10 | } 11 | 12 | dispatch({type: constants.Requesting}) 13 | 14 | http[method](url, data).then((res) => { 15 | let _action = { 16 | type: constants.Requested, 17 | name, 18 | result: res.data 19 | } 20 | dispatch(_action) 21 | }).catch((error) => { 22 | dispatch({type: constants.RequestError}) 23 | }) 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /redux/middleware/src/redux/middleware.js: -------------------------------------------------------------------------------- 1 | import http from '../utils/httpclient' 2 | import * as constants from '../components/datagrid/datagridconstants' 3 | 4 | export default function(api){ 5 | return function(dispatch){ 6 | return function(action){ 7 | let {type, types, url, data, method = 'get', name} = action; 8 | if(!url){ 9 | return dispatch(action) 10 | } 11 | 12 | dispatch({type: constants.Requesting}) 13 | 14 | http[method](url, data).then((res) => { 15 | let _action = { 16 | type: constants.Requested, 17 | name, 18 | result: res.data 19 | } 20 | dispatch(_action) 21 | }).catch((error) => { 22 | dispatch({type: constants.RequestError}) 23 | }) 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /reactERP/src/modules/cp/cp.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | let Login = (props) => { 4 | return ; 5 | } 6 | 7 | 8 | let Logout = (props) => { 9 | return ; 10 | } 11 | 12 | export default Login 13 | 14 | // export default class CP extends React.Component{ 15 | // state = { 16 | // status: 0 17 | // } 18 | 19 | // login(){ 20 | // this.setState({status: 1}) 21 | // } 22 | 23 | // logout(){ 24 | // this.setState({status: 0}) 25 | // } 26 | 27 | // render(){ 28 | // let button = null; 29 | // if(this.state.status == 0){ 30 | // button = 31 | // } else { 32 | // button = 33 | // } 34 | 35 | // return
{button}
36 | // } 37 | // } -------------------------------------------------------------------------------- /reactERP/src/modules/login/LoginReducer.js: -------------------------------------------------------------------------------- 1 | // import httpclient from '../../utils/HttpClient' 2 | import * as LoginConstants from './LoginConstants'; 3 | import { combineReducers } from 'redux'; 4 | import update from 'react-addons-update' 5 | function login(state = [], action){ 6 | 7 | // httpclient.post(action.url, action.data).then(response => { 8 | // console.log(response); 9 | // state.state = response.state; 10 | // return state; 11 | // }) 12 | 13 | // return state; 14 | 15 | // state.dataset = action.response.data.data; 16 | // console.log(action); 17 | const newData = update(state, {$push: [action.body]}); 18 | // console.log(newData, state); 19 | return newData; 20 | } 21 | 22 | function getCode(state = {}, action){ 23 | return state; 24 | } 25 | 26 | const logineReducer = combineReducers( 27 | { 28 | login, 29 | getCode 30 | } 31 | ); 32 | 33 | export default logineReducer; -------------------------------------------------------------------------------- /component/src/style/README.md: -------------------------------------------------------------------------------- 1 | ## 普通样式名称使用 —— className 2 | app.css 3 | ```css 4 | .c1{ 5 | color: red; 6 | width: 100%; 7 | height: 300px; 8 | border: solid 1px red; 9 | } 10 | ``` 11 | app.js 12 | ```javascript 13 | import './app.css' 14 | 15 | import React from 'react'; 16 | import ReactDOM from 'react-dom'; 17 | 18 | import './modules/cp/cp.scss' 19 | class Component1 extends React.Component{ 20 | render(){ 21 | return ( 22 |
23 | ) 24 | } 25 | } 26 | 27 | ReactDOM.render( 28 | , 29 | document.getElementById('app') 30 | ) 31 | ``` 32 | 33 | ## 行内样式 34 | ```javascript 35 | let c1 = { 36 | color: 'red', 37 | width: '100%', 38 | height: '300px', 39 | border: 'solid 1px red' 40 | } 41 | class Component1 extends React.Component{ 42 | render(){ 43 | console.log(c1) 44 | return ( 45 |
46 | ) 47 | } 48 | } 49 | ``` -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | .fa-icon-rotate(@degrees, @rotation) { 15 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 16 | -webkit-transform: rotate(@degrees); 17 | -ms-transform: rotate(@degrees); 18 | transform: rotate(@degrees); 19 | } 20 | 21 | .fa-icon-flip(@horiz, @vert, @rotation) { 22 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 23 | -webkit-transform: scale(@horiz, @vert); 24 | -ms-transform: scale(@horiz, @vert); 25 | transform: scale(@horiz, @vert); 26 | } 27 | -------------------------------------------------------------------------------- /reactERP/src/components/home/header/header.scss: -------------------------------------------------------------------------------- 1 | @import '../../../libs/common/global.scss'; 2 | 3 | .dk-header{ 4 | position: fixed; 5 | top: 0; 6 | width: 100%; 7 | height: 42px; 8 | border-bottom: solid 1px #ccc; 9 | /*logo*/ 10 | >ul:first-child{ 11 | width: 200px; 12 | height: 100%; 13 | float: left; 14 | li{ 15 | width: 100%; 16 | height: 100%; 17 | padding: 4px 15px; 18 | font-family: 'Raleway', sans-serif; 19 | font-size: 25px; 20 | a{ 21 | color: #666666; 22 | } 23 | } 24 | } 25 | /*right*/ 26 | >ul:last-child{ 27 | height: 100%; 28 | float: right; 29 | padding-right: 20px; 30 | li{ 31 | // width: 48px; 32 | height: 100%; 33 | position: relative; 34 | text-align: center; 35 | padding: 15px; 36 | float: left; 37 | a{color: #666666;} 38 | i{font-size: 18px;} 39 | span{position: absolute; top: 5px; left: 3px; font-size: 10px; padding: 2px 5px;} 40 | } 41 | li:last-child{ 42 | width: auto; 43 | padding: 15px; 44 | } 45 | li:hover{ 46 | background-color: #eceeef; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /reactERP/src/libs/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 16 | -webkit-transform: rotate($degrees); 17 | -ms-transform: rotate($degrees); 18 | transform: rotate($degrees); 19 | } 20 | 21 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 22 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}); 23 | -webkit-transform: scale($horiz, $vert); 24 | -ms-transform: scale($horiz, $vert); 25 | transform: scale($horiz, $vert); 26 | } 27 | -------------------------------------------------------------------------------- /reactERP/src/components/modal/modalcomponent.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | 3 | import DatagridComponent from '../datagrid/datagridcomponent' 4 | 5 | import './modal.css' 6 | 7 | class ModalComponent extends Component{ 8 | cancel(){ 9 | this.props.cb(); 10 | } 11 | render(){ 12 | let content = null; 13 | if(this.props.config.type == 'datagrid'){ 14 | content = 15 | } else { 16 | content =

modal

17 | } 18 | 19 | let html = ( 20 |
21 |
22 |
23 |
Modal Header
24 | × 25 |
26 |
27 | {content} 28 |
29 |
30 |
31 |
32 | ) 33 | return this.props.show ? html : null; 34 | } 35 | } 36 | 37 | export default ModalComponent; -------------------------------------------------------------------------------- /reactERP/src/modules/order/orderComponent.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {connect} from 'react-redux' 3 | import * as orderActions from './orderAction'; 4 | import PropTypes from 'prop-types' 5 | 6 | 7 | class OrderComponent extends React.Component{ 8 | scanHandler(){ 9 | this.props.scanCode(); 10 | } 11 | printHandler(){ 12 | this.props.print(); 13 | } 14 | render(){ 15 | return ( 16 |
17 |

18 |

19 |
    20 |
  • {this.props.name}
  • 21 |
  • {this.props.price}
  • 22 |
23 |

{this.props.order.scanCode.length}

24 |
25 | ) 26 | } 27 | } 28 | 29 | OrderComponent.propTypes = { 30 | name: PropTypes.string.isRequired 31 | } 32 | 33 | // const mapStateToProps = state => ({order: state.order}) 34 | // state == store 35 | const mapStateToProps = (store) => { 36 | return { 37 | order: store.order 38 | } 39 | } 40 | export default connect(mapStateToProps, orderActions)(OrderComponent) 41 | 42 | // export default OrderComponent; -------------------------------------------------------------------------------- /js/react-dom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ReactDOM v15.0.1 3 | * 4 | * Copyright 2013-present, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | * 11 | */ 12 | // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js 13 | ;(function(f) { 14 | // CommonJS 15 | if (typeof exports === "object" && typeof module !== "undefined") { 16 | module.exports = f(require('react')); 17 | 18 | // RequireJS 19 | } else if (typeof define === "function" && define.amd) { 20 | define(['react'], f); 21 | 22 | // 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 34 | 35 | -------------------------------------------------------------------------------- /component/src/state/README.md: -------------------------------------------------------------------------------- 1 | ## state 2 | state 可以理解成 props,不一样的在于 props 是只读的,而 state 是可读写。当 state 发生改变的时候会重新执行 render 方法去渲染整颗 DOM 树,在渲染的过程中会有 diff 算法去计算哪些 DOM 有更新,从而提升性能。 3 | 在使用 state 前要先初始化 `getInitialState` 4 | 更改 state 一定要用 `setState` 5 | `getInitialState` 该方法在每次 render 时都会被调用一次。 6 | ```javascript 7 | //es5 8 | var StateComponent = React.createClass({ 9 | getInitialState: function(){ 10 | return { 11 | text: '' 12 | } 13 | }, 14 | change: function(event){ 15 | this.setState({text: event.target.value}); 16 | }, 17 | render: function(){ 18 | return ( 19 |
20 |

21 |

{this.state.text}

22 |
23 | ) 24 | } 25 | }) 26 | 27 | //es6 28 | import React from 'react'; 29 | import ReactDOM from 'react-dom'; 30 | class Component1 extends React.Component{ 31 | state = { 32 | text: '' 33 | } 34 | change(event){ 35 | this.setState({text: event.target.value}); 36 | }, 37 | render(){ 38 | return ( 39 |
40 |

41 |

{this.state.text}

42 |
43 | ) 44 | } 45 | } 46 | ``` 47 | [效果预览](https://dk-lan.github.io/react/component/src/state/state.html) 48 | -------------------------------------------------------------------------------- /reactERP/src/components/home/header/header.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import {Link} from 'react-router' 3 | import './header.scss' 4 | 5 | class HeaderComponent extends Component{ 6 | render(){ 7 | return ( 8 |
9 |
    10 |
  • PrintERP
  • 11 |
12 |
    13 |
  • 14 | 15 | 16 | 2 17 | 18 |
  • 19 |
  • 20 | 21 | 22 | 2 23 | 24 |
  • 25 |
  • 26 | 27 | Adminstrator 28 | 29 |
  • 30 |
31 |
32 | ) 33 | } 34 | } 35 | 36 | export default HeaderComponent -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 认识 React 2 | React 是 facebook 开源的一套框架,可总结为以下几个特点: 3 | - 基于 JSX 语法糖实现 4 | - JUST THE UI:在多层架构的设计模式中,React 并不算 MVC 的架构,它可理解为 MVC 的 V 层。 5 | - VIRTUAL DOM:虚拟DOM,是轻量的 js 对象,只保留了原生 dom 的一些常用的属性和方法。 6 | - DATA FLOW: React是单向响应的数据流。 7 | 8 | # 技术点 9 | - [JSX 语法](https://github.com/dk-lan/react/tree/master/jsx) 10 | - [组件定义](https://github.com/dk-lan/react/tree/master/component/src/define) 11 | - [组件渲染](https://github.com/dk-lan/react/tree/master/component/src/render) 12 | - [组件事件](https://github.com/dk-lan/react/tree/master/component/src/event) 13 | - [state](https://github.com/dk-lan/react/tree/master/component/src/state) 14 | - [样式绑定](https://github.com/dk-lan/react/tree/master/component/src/style) 15 | - [表单](https://github.com/dk-lan/react/tree/master/component/src/form) 16 | - [组件通信](https://github.com/dk-lan/react/tree/master/component/src/communication) 17 | - [生命周期](https://github.com/dk-lan/react/tree/master/component/src/lifecycle) 18 | - [路由(3.0)](https://github.com/dk-lan/react/tree/master/router) 19 | - Redux 20 | - [Redux 简介和简单实现](https://github.com/dk-lan/react/tree/master/redux) 21 | - [Redux 跨组件通信之入门篇 —— combineReducers](https://github.com/dk-lan/react/tree/master/redux/combineReducers) 22 | - [Redux 跨组件通信之进阶篇 —— Provider 和 connect](https://github.com/dk-lan/react/tree/master/redux/connetProvider) 23 | - [Redux 跨组件通信之高级篇 —— 中间件](https://github.com/dk-lan/react/tree/master/redux/middleware) 24 | - [项目应用](https://dk-lan.github.io/react/reactERP/index.html#/login) -------------------------------------------------------------------------------- /reactERP/src/components/login/login.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | 3 | import './login.scss' 4 | 5 | class LoginComponent extends Component{ 6 | login(){ 7 | console.log(this) 8 | this.props.router.push({pathname: '/home/cnode'}) 9 | } 10 | render(){ 11 | return ( 12 |
13 |
14 |

登录

15 |
16 |
17 | 18 | 19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 |
27 |
28 |
29 |
2017 © dk by www.dk-lan.com
30 |
31 | ) 32 | } 33 | } 34 | 35 | export default LoginComponent -------------------------------------------------------------------------------- /reactERP/src/components/modal/modal.css: -------------------------------------------------------------------------------- 1 | .Marco-modal * {margin: 0;padding: 0;box-sizing:content-box;} 2 | .Marco-modal .Marco-modalShade{position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: #000; opacity: .3; z-index: 99;} 3 | .Marco-modal .Marco-modalBody{position: fixed;background: #fff;border:1px solid #666;border-radius:5px;left: 50%;top: 50%;transform:translate(-50%,-50%);z-index:100;min-width:500px;} 4 | .Marco-modal .Marco-modalBody .Marco-modalHeader{height: 30px;padding: 16px;border-bottom:1px solid #ccc;} 5 | .Marco-modal .Marco-modalBody .Marco-modalHeader .Marco-modalClose{position: absolute;top: 5px;right: 10px;display: block;width: 30px;height: 30px;text-align: center;line-height: 22px;font-size:30px;cursor:pointer;} 6 | .Marco-modal .Marco-modalBody .Marco-modalHeader .Marco-modalClose:hover{background: #f00;color:#fff;} 7 | .Marco-modal .Marco-modalBody .Marco-modalMain{min-height: 40px;padding: 16px;max-height:490px;overflow: auto;} 8 | .Marco-modal .Marco-modalBody .Marco-modalBtn{height: 40px;padding: 16px;border-top:1px solid #ccc;} 9 | .Marco-modal .Marco-modalBody .Marco-modalBtn .btn{float: right;margin-right: 10px;color:#fff;padding: 6px 12px;border:0 none;font-size:18px;border-radius:5px;cursor:pointer;} 10 | .Marco-modal .Marco-modalBody .Marco-modalBtn .btn:hover{opacity:.7;} 11 | .Marco-modal .Marco-modalBody .Marco-modalBtn .btn.btnSecondary{background: #aab;} 12 | .Marco-modal .Marco-modalBody .Marco-modalBtn .btn.btnPrimary{background: #0bf;} -------------------------------------------------------------------------------- /component/src/state/state.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React-Component-state 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 40 | 41 | -------------------------------------------------------------------------------- /reactERP/src/components/spinner/spinner.scss: -------------------------------------------------------------------------------- 1 | .dk-spinner-mask { 2 | position: fixed; 3 | top: 0; 4 | right: 0; 5 | bottom: 0; 6 | left: 0; 7 | background-color: #fff; 8 | opacity: .4; 9 | z-index: 2090; 10 | } 11 | 12 | .dk-spinner-three-bounce.dk-spinner { 13 | position: absolute; 14 | top: 53%; 15 | left: 47%; 16 | background-color: none!important; 17 | z-index: 2099; 18 | margin: 0 auto; 19 | width: 70px; 20 | text-align: center; 21 | } 22 | 23 | .dk-spinner-three-bounce div { 24 | width: 18px; 25 | height: 18px; 26 | background-color: #1ab394; 27 | border-radius: 100%; 28 | display: inline-block; 29 | -webkit-animation: dk-threeBounceDelay 1.4s infinite ease-in-out; 30 | animation: dk-threeBounceDelay 1.4s infinite ease-in-out; 31 | -webkit-animation-fill-mode: both; 32 | animation-fill-mode: both; 33 | } 34 | 35 | .dk-spinner-three-bounce .dk-bounce1 { 36 | -webkit-animation-delay: -.32s; 37 | animation-delay: -.32s; 38 | } 39 | 40 | .dk-spinner-three-bounce .dk-bounce2 { 41 | -webkit-animation-delay: -.16s; 42 | animation-delay: -.16s; 43 | } 44 | 45 | @-webkit-keyframes dk-threeBounceDelay{ 46 | 0%, 47 | 100%, 48 | 80%{-webkit-transform:scale(0); transform:scale(0)} 49 | 40%{-webkit-transform:scale(1);transform:scale(1)} 50 | } 51 | @keyframes dk-threeBounceDelay{ 52 | 0%, 53 | 100%, 54 | 80%{-webkit-transform:scale(0);transform:scale(0)} 55 | 40%{-webkit-transform:scale(1);transform:scale(1)} 56 | } -------------------------------------------------------------------------------- /component/src/define/define.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React-Component-define 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 43 | 44 | -------------------------------------------------------------------------------- /redux/middleware/src/components/spinner/spinner.scss: -------------------------------------------------------------------------------- 1 | .dk-spinner-mask { 2 | position: fixed; 3 | top: 0; 4 | right: 0; 5 | bottom: 0; 6 | left: 0; 7 | background-color: #fff; 8 | opacity: .4; 9 | z-index: 2090; 10 | } 11 | 12 | .dk-spinner-three-bounce.dk-spinner { 13 | position: absolute; 14 | top: 53%; 15 | left: 47%; 16 | background-color: none!important; 17 | z-index: 2099; 18 | margin: 0 auto; 19 | width: 70px; 20 | text-align: center; 21 | } 22 | 23 | .dk-spinner-three-bounce div { 24 | width: 18px; 25 | height: 18px; 26 | background-color: #1ab394; 27 | border-radius: 100%; 28 | display: inline-block; 29 | -webkit-animation: dk-threeBounceDelay 1.4s infinite ease-in-out; 30 | animation: dk-threeBounceDelay 1.4s infinite ease-in-out; 31 | -webkit-animation-fill-mode: both; 32 | animation-fill-mode: both; 33 | } 34 | 35 | .dk-spinner-three-bounce .dk-bounce1 { 36 | -webkit-animation-delay: -.32s; 37 | animation-delay: -.32s; 38 | } 39 | 40 | .dk-spinner-three-bounce .dk-bounce2 { 41 | -webkit-animation-delay: -.16s; 42 | animation-delay: -.16s; 43 | } 44 | 45 | @-webkit-keyframes dk-threeBounceDelay{ 46 | 0%, 47 | 100%, 48 | 80%{-webkit-transform:scale(0); transform:scale(0)} 49 | 40%{-webkit-transform:scale(1);transform:scale(1)} 50 | } 51 | @keyframes dk-threeBounceDelay{ 52 | 0%, 53 | 100%, 54 | 80%{-webkit-transform:scale(0);transform:scale(0)} 55 | 40%{-webkit-transform:scale(1);transform:scale(1)} 56 | } -------------------------------------------------------------------------------- /reactERP/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "course-react", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack --progress --colors", 9 | "start": "webpack-dev-server --devtool eval --progress --port 1703 --colors --content-base ./" 10 | }, 11 | "devDependencies": { 12 | "babel-core": "^6.0.0", 13 | "babel-loader": "^6.0.0", 14 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 15 | "babel-preset-latest": "^6.0.0", 16 | "babel-preset-react": "^6.24.1", 17 | "babel-preset-stage-2": "^6.24.1", 18 | "css-loader": "^0.25.0", 19 | "extract-text-webpack-plugin": "^2.1.0", 20 | "file-loader": "^0.9.0", 21 | "image-webpack-loader": "^3.3.0", 22 | "node-sass": "^4.9.0", 23 | "progress-bar-webpack-plugin": "^1.9.3", 24 | "react": "^15.5.4", 25 | "react-addons-update": "^15.6.0", 26 | "react-dom": "^15.5.4", 27 | "react-redux": "^5.0.5", 28 | "react-router": "^3.0.2", 29 | "react-router-redux": "^4.0.8", 30 | "redux": "^3.6.0", 31 | "redux-thunk": "^2.2.0", 32 | "sass-loader": "^5.0.1", 33 | "style-loader": "^0.16.1", 34 | "superagent": "^3.5.2", 35 | "url-loader": "^0.5.8", 36 | "webpack": "^2.2.0", 37 | "webpack-dev-server": "^2.2.0" 38 | }, 39 | "author": "DK.Lan", 40 | "license": "ISC", 41 | "dependencies": { 42 | "element-react": "^1.1.4", 43 | "element-theme-default": "^1.4.2", 44 | "events": "^1.1.1", 45 | "flux": "^3.1.2" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /redux/middleware/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "course-react", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack --progress --colors", 9 | "start": "webpack-dev-server --devtool eval --progress --port 1703 --colors --content-base ./" 10 | }, 11 | "devDependencies": { 12 | "babel-core": "^6.0.0", 13 | "babel-loader": "^6.0.0", 14 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 15 | "babel-preset-latest": "^6.0.0", 16 | "babel-preset-react": "^6.24.1", 17 | "babel-preset-stage-2": "^6.24.1", 18 | "css-loader": "^0.25.0", 19 | "extract-text-webpack-plugin": "^2.1.0", 20 | "file-loader": "^0.9.0", 21 | "image-webpack-loader": "^3.3.0", 22 | "node-sass": "^4.9.0", 23 | "progress-bar-webpack-plugin": "^1.9.3", 24 | "react": "^15.5.4", 25 | "react-addons-update": "^15.6.0", 26 | "react-dom": "^15.5.4", 27 | "react-redux": "^5.0.5", 28 | "react-router": "^3.0.2", 29 | "react-router-redux": "^4.0.8", 30 | "redux": "^3.6.0", 31 | "redux-thunk": "^2.2.0", 32 | "sass-loader": "^5.0.1", 33 | "style-loader": "^0.16.1", 34 | "superagent": "^3.5.2", 35 | "url-loader": "^0.5.8", 36 | "webpack": "^2.2.0", 37 | "webpack-dev-server": "^2.2.0" 38 | }, 39 | "author": "DK.Lan", 40 | "license": "ISC", 41 | "dependencies": { 42 | "element-react": "^1.1.4", 43 | "element-theme-default": "^1.4.2", 44 | "events": "^1.1.1", 45 | "flux": "^3.1.2" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /jsx/jsx.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React-JSX 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 | 19 | 20 | 45 | 46 | -------------------------------------------------------------------------------- /reactERP/src/components/home/nav/nav.scss: -------------------------------------------------------------------------------- 1 | @import '../../../libs/common/global.scss'; 2 | .dk-nav-content{position: absolute; top: 0; bottom: 0; left: 0; width: 228px; border-right: solid 1px #ccc; 3 | overflow-x: hidden; overflow-y: auto; 4 | transition: width 0.5s; 5 | .dk-nav-item{ 6 | max-height: 40px; 7 | overflow: hidden; 8 | transition: max-height 0.5s; 9 | border-bottom: solid 1px #ccc; 10 | >a:not(.btn){ 11 | padding: 10px 15px; display: block; 12 | overflow: hidden; white-space: nowrap; text-overflow:ellipsis; 13 | i{color: $main-color; margin-right: 5px; font-size: 16px;} 14 | >i:last-child{float: right; margin-top: 2px; transition: transform 0.5s;} 15 | } 16 | .dk-sub-nav{ 17 | width: 100%; 18 | overflow: hidden; 19 | li{ 20 | width: 100%; 21 | >a{ 22 | display: block; 23 | padding-left: 37px; 24 | padding-top: 5px; 25 | padding-bottom: 5px; 26 | } 27 | } 28 | } 29 | *:not(:first-child){ 30 | transition: opacity 0.5s; 31 | opacity: 1; 32 | } 33 | } 34 | .dk-nav-item.active{ 35 | max-height: 200px; 36 | transition: max-height 0.5s; 37 | >a{ 38 | background-color: #D9D9D9; 39 | >i:last-child{transition: transform 0.5s;float: right; margin-top: 2px; transform: rotate(-90deg);} 40 | } 41 | } 42 | .dk-nav-item.nav-toggle{ 43 | text-align: right; 44 | height: 50px; 45 | max-height: 50px; 46 | padding: 10px 20px; 47 | .btn{ 48 | padding: 3px 8px; 49 | } 50 | } 51 | } 52 | 53 | .dk-nav-content.toggle{ 54 | transition: width 0.5s; 55 | width: 50px; 56 | .dk-nav-item { 57 | text-align: center; 58 | padding: 5px 0; 59 | *:not(:first-child){ 60 | transition: opacity 0.5s; 61 | opacity: 0; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /reactERP/src/modules/login/LoginComponent.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import * as loginActions from './LoginAction'; 3 | import {connect} from 'react-redux' 4 | // import {Input} from 'element-react'; 5 | // import 'element-theme-default'; 6 | 7 | class LoginComponent extends Component{ 8 | loginHandler(){ 9 | this.props.login(); 10 | } 11 | render(){ 12 | return ( 13 |
14 |
15 | 18 |
19 | 20 |
21 |
22 |
23 | 26 |
27 | 28 |
29 |
30 | 31 | 32 |

{this.props.a}

33 |
34 | ) 35 | } 36 | } 37 | 38 | // const mapStateToProps = state => ({ 39 | // loading: false, 40 | // }) 41 | 42 | const mapStateToProps = (state) => { 43 | return { 44 | loading: false, 45 | a: state.login.login.a 46 | } 47 | } 48 | export default connect(mapStateToProps, loginActions)(LoginComponent) -------------------------------------------------------------------------------- /redux/middleware/src/utils/HttpClient.js: -------------------------------------------------------------------------------- 1 | import request from 'superagent' 2 | 3 | const LOCAL_SERVER = 'http://localhost:888/'; 4 | 5 | const DEV_SERVER = ''; 6 | const PRO_SERVER = 'http://www.dk-lan.com/cloudapi/'; 7 | 8 | function getUrl(path) { 9 | if (path.startsWith('http')) { 10 | return path; 11 | } 12 | return `${PRO_SERVER}${path}`; 13 | } 14 | 15 | const errorHandler = (err) => { 16 | var str = err.response.status 17 | str += ' - ' 18 | str += err.response.statusText 19 | str += '
请求路径:
' 20 | str += err.response.error.url 21 | console.log(str); 22 | } 23 | 24 | const HttpClient = { 25 | get: (path, query) => new Promise((resolve, reject) => { 26 | var req = request 27 | .get(getUrl(path)) 28 | .query(query) 29 | .set('Authorization', window.localStorage.getItem('access_token')) 30 | .end((err, res) => { 31 | if (err) { 32 | errorHandler(err) 33 | reject(err); 34 | } else { 35 | resolve(res.body); 36 | } 37 | }); 38 | }), 39 | 40 | post: (path, formdata, query) => new Promise((resolve, reject) => { 41 | request 42 | .post(getUrl(path)) 43 | .set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8') 44 | .query(query) 45 | .send(formdata) 46 | .end((err, res) => { 47 | if (err) { 48 | errorHandler(err) 49 | reject(err); 50 | } else { 51 | resolve(res.body); 52 | } 53 | }); 54 | }) 55 | }; 56 | 57 | export default HttpClient; 58 | -------------------------------------------------------------------------------- /reactERP/src/utils/ajaxMiddleware.js: -------------------------------------------------------------------------------- 1 | import http from '../utils/HttpClient'; 2 | 3 | export function ajaxMiddleware({ dispatch, getState }) { 4 | 5 | return next => action => { 6 | const { 7 | types, 8 | shouldCallAPI = () => true, 9 | query = {}, 10 | payload = {}, 11 | method = "get", 12 | path 13 | } = action; 14 | 15 | 16 | // if (!types) { 17 | // // Normal action: pass it on 18 | // return next(action); 19 | // } 20 | 21 | 22 | 23 | if (!path || !method) { 24 | return next(action) 25 | // throw new Error('path and method is required!'); 26 | } 27 | 28 | if (!Array.isArray(types) || types.length !== 3 || !types.every(type => typeof type === 'string')) { 29 | throw new Error('Expected an array of three string types.'); 30 | } 31 | 32 | if (!shouldCallAPI(getState())) { 33 | return; 34 | } 35 | 36 | const [requestType, successType, failureType] = types; 37 | 38 | dispatch(Object.assign({}, { query }, { payload }, { 39 | type: requestType, 40 | })); 41 | 42 | return http[method](path, query, payload) 43 | .then( 44 | response => dispatch(Object.assign({}, { query }, { payload }, { 45 | type: successType, 46 | body: response, 47 | lastFetched: Date.now() 48 | })), 49 | error => dispatch(Object.assign({}, { query }, { payload }, { 50 | type: failureType, 51 | error 52 | })) 53 | ); 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /reactERP/src/components/home/nav/nav.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react' 2 | import {Link} from 'react-router' 3 | import './nav.scss' 4 | 5 | export default class NavComponent extends Component{ 6 | toggleNav(){} 7 | toggleNavItem(){} 8 | render(){ 9 | return ( 10 |
11 | 44 |
45 | ) 46 | } 47 | } -------------------------------------------------------------------------------- /component/src/render/condition-rendering.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React-Component-define 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 56 | 57 | -------------------------------------------------------------------------------- /component/src/form/input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React-Component-define 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 46 | 47 | -------------------------------------------------------------------------------- /reactERP/src/components/cnode/cnode.js: -------------------------------------------------------------------------------- 1 | import './cnode.scss' 2 | 3 | import React from 'react' 4 | import Datagrid from '../../components/datagrid/datagridcomponent' 5 | import Modal from '../../components/modal/modalcomponent' 6 | 7 | export default class CNodeComponent extends React.Component{ 8 | static defaultProps = { 9 | cnode: { 10 | config: { 11 | url: 'https://cnodejs.org/api/v1/topics', 12 | data: {page: 1, limit: 10}, 13 | cols: ['title', 'reply_count', 'top', 'create_at', 'last_reply_at'], 14 | name: 'cnode' 15 | } 16 | }, 17 | modal: { 18 | config: { 19 | type: 'datagrid', 20 | url: 'https://cnodejs.org/api/v1/topics', 21 | data: {page: 3, limit: 5}, 22 | cols: ['title'], 23 | name: 'modal' 24 | } 25 | } 26 | } 27 | state = { 28 | modalShow: false, 29 | title: '' 30 | } 31 | filldata(_data = {}){ 32 | this.setState({ 33 | modalShow: false, 34 | title: _data.title || this.state.title 35 | }) 36 | } 37 | componentDidMount(){ 38 | this.props.router.setRouteLeaveHook( 39 | this.props.route, 40 | this.routerWillLeave 41 | ) 42 | } 43 | routerWillLeave(){ 44 | return '确认要离开?' 45 | } 46 | showup(){ 47 | this.setState({ 48 | modalShow: true 49 | }) 50 | } 51 | render(){ 52 | return ( 53 |
54 |
55 |
56 | 57 |
...
58 |
59 |
60 | 61 | 62 |
63 | ) 64 | } 65 | } -------------------------------------------------------------------------------- /redux/middleware/src/components/datagrid/datagridcomponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {connect} from 'react-redux' 3 | 4 | import SpinnerComponent from '../spinner/spinner' 5 | 6 | import * as actions from './datagridaction' 7 | 8 | class DatagridComponent extends React.Component{ 9 | getKeys(item){ 10 | let cols = item ? Object.keys(item) : []; 11 | return this.props.config.cols || cols; 12 | } 13 | 14 | componentWillMount(){ 15 | this.props.refresh(this.props.config) 16 | } 17 | render(){ 18 | return ( 19 |
20 | 21 | 22 | 23 | { 24 | this.getKeys(this.props.dataset[0]).map((key) => { 25 | return 26 | }) 27 | } 28 | 29 | 30 | 31 | { 32 | this.props.dataset.map((item) => { 33 | return ( 34 | 35 | { 36 | this.getKeys(item).map((key) => { 37 | return 38 | }) 39 | } 40 | 41 | ) 42 | }) 43 | } 44 | 45 | 46 |
{key}
{item[key]}
47 | 48 |
49 | ) 50 | } 51 | } 52 | 53 | const mapStateToProps = (state) => { 54 | return { 55 | dataset: state.datagrid.dataset || [], 56 | show: state.datagrid.show, 57 | error: state.datagrid.error 58 | } 59 | } 60 | 61 | export default connect(mapStateToProps, actions)(DatagridComponent); -------------------------------------------------------------------------------- /redux/README.md: -------------------------------------------------------------------------------- 1 | # Redux 2 | 前端框架的组件式开发永远有一道鸿沟——跨组件通信。我在 [Vue 教程](https://github.com/dk-lan/vue/tree/master/VueBasic/Vuex)中有提到过,如果对跨组件通信不明白的可先跳过去看看。 3 | 4 | React 不同与双向数据绑定框架,它是单向数据流,所以每次更新都得调用`setState`,所以在跨组件通信中会比较迂回。还有就是 React 没有逻辑分层,在开发过程中,逻辑分层是很重要的。 5 | 6 | Redux 实现了跨组件通信和逻辑分层的好处,所以在 React 中使用 Redux 更配。 7 | 8 | # Redux 简单实现 9 | 为了说明问题,先来一个公共对象实现跨组件通信。当然这个也是 flux 的实现原理。 10 | ##### actions.js 11 | ```javascript 12 | export default { 13 | increment(){ 14 | return { 15 | type: "+" 16 | } 17 | }, 18 | decrement(){ 19 | return { 20 | type: '-' 21 | } 22 | } 23 | } 24 | ``` 25 | ##### reducer 26 | ```javascript 27 | export default (state = 0, action) => { 28 | switch(action.type){ 29 | case '+': 30 | return state + 1; 31 | case '-': 32 | return state - 1; 33 | default: 34 | return state; 35 | } 36 | } 37 | ``` 38 | #### component 39 | ```javascript 40 | import React, {Component} from 'react' 41 | import {createStore} from 'redux' 42 | import Actions from './actions' 43 | import Reducer from './reducer' 44 | 45 | const store = createStore(Reducer); 46 | 47 | export default class Component1 extends Component{ 48 | constructor(props){ 49 | super(props); 50 | this.state = {count: 0} 51 | } 52 | increment = () => { 53 | store.dispatch(Actions.increment()); 54 | this.setState({ 55 | count: store.getState() 56 | }) 57 | } 58 | 59 | render(){ 60 | return ( 61 |
62 |

component-cp1-{this.state.count}

63 | 64 |
65 | ) 66 | } 67 | } 68 | ``` 69 | 70 | ### 小结——分层 71 | - Actions 层 72 | - 用户行为操作,由用户在 View 层触发 `store.dispatch(Actions.increment());` 73 | - 行为操作应该为一个 `function`且必须返回有`type`属性的对象 74 | - 每个方法都应该由`store`进行派发。 75 | - Reducer 层 76 | - 必须是一个纯函数(一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用) 77 | - 接受两个参数,第一个为`state`,另一个为`action` 78 | - `return`的结果可以用`store.getState()`来接收 79 | - Store 层 80 | - `redux`的一个方法,接受`reducer`,返回一个对象`store` 81 | - 对象`store`的方法`dispath`用于派发`action` 82 | - 通过`dispath`派发的`action`会触发`reducer` 83 | - View 层 84 | - 视图层,也就是组件 85 | - 通过`getState()`获取的值然后再`setState`便可以显示。 86 | -------------------------------------------------------------------------------- /reactERP/src/utils/HttpClient.js: -------------------------------------------------------------------------------- 1 | import request from 'superagent' 2 | 3 | const LOCAL_SERVER = 'http://localhost:888/'; 4 | 5 | const DEV_SERVER = ''; 6 | const PRO_SERVER = 'http://www.dk-lan.com/cloudapi/'; 7 | 8 | function getUrl(path) { 9 | if (path.startsWith('http')) { 10 | return path; 11 | } 12 | return `${PRO_SERVER}${path}`; 13 | } 14 | 15 | const errorHandler = (err) => { 16 | var str = err.response.status 17 | str += ' - ' 18 | str += err.response.statusText 19 | str += '
请求路径:
' 20 | str += err.response.error.url 21 | console.log(str); 22 | } 23 | 24 | const HttpClient = { 25 | get: (path, query) => new Promise((resolve, reject) => { 26 | // if(!window.localStorage.getItem('access_token')){ 27 | // router.push({name: 'login'}); 28 | // return false; 29 | // } 30 | var req = request 31 | .get(getUrl(path)) 32 | .query(query) 33 | .set('Authorization', window.localStorage.getItem('access_token')) 34 | .end((err, res) => { 35 | if (err) { 36 | errorHandler(err) 37 | reject(err); 38 | } else { 39 | resolve(res.body); 40 | } 41 | }); 42 | }), 43 | 44 | post: (path, formdata, query) => new Promise((resolve, reject) => { 45 | // if(path.indexOf('login/index') < 0 && !window.localStorage.getItem('access_token')){ 46 | // router.push({name: 'login'}); 47 | // return false; 48 | // } 49 | request 50 | .post(getUrl(path)) 51 | .set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8') 52 | .set('Authorization', window.localStorage.getItem('access_token')) 53 | .query(query) 54 | .send(formdata) 55 | .end((err, res) => { 56 | if (err) { 57 | errorHandler(err) 58 | reject(err); 59 | } else { 60 | if(path.indexOf('login/index') > -1){ 61 | window.localStorage.setItem('access_token', res.body.token_type + ' ' + res.body.access_token) 62 | } 63 | resolve(res.body); 64 | } 65 | }); 66 | }) 67 | }; 68 | 69 | export default HttpClient; 70 | -------------------------------------------------------------------------------- /router/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 路由-基本用法 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 60 | 61 | -------------------------------------------------------------------------------- /reactERP/src/libs/common/common.scss: -------------------------------------------------------------------------------- 1 | @import './global.scss'; 2 | 3 | html{width: 100%; height: 100%;} 4 | body{font-family:"open sans","Helvetica Neue",Helvetica,Arial,sans-serif; color:#676a6c; width: 100%; height: 100%; font-size: 13px} 5 | ul{padding:0; margin:0;} 6 | li{list-style:none;} 7 | 8 | /*a*/ 9 | a, a:focus{color:#000;} 10 | a:hover{text-decoration:none; color: $main-color;} 11 | a:active{text-decoration:none;} 12 | a:visited{text-decoration:none;} 13 | a:link{text-decoration:none;} 14 | 15 | /*validattion*/ 16 | input.valid-false{border-color: #ed5565;} 17 | input.valid-true{border-color: $main-color;} 18 | div.valid-false{color: #ed5565; font-size: 12px;} 19 | 20 | /*reset btn-primary*/ 21 | .btn-primary, .btn-primary:focus{background-color: $main-color; border-color: $main-color; color: #fff;} 22 | .btn-primary:hover{background-color: $main-color-hover; border-color: $main-color-hover;} 23 | .badge-primary{background-color: $main-color;} 24 | 25 | .dk-toolbar{padding: 10px 20px;background-color: #EFEFEF;width: 100%;height: 50px;text-align: right; } 26 | .dk-toolbar.dk-grid-toolbar {text-align: left;} 27 | .dk-toolbar>.btn{margin-right: 10px;} 28 | .dk-toolbar>.btn.btn-goback{background-color:#e6674a; border-color:#e6674a;} 29 | 30 | .dk-form{padding:10px;} 31 | .dk-form>form.form-horizontal>div.form-group{margin:0; margin-bottom:15px; min-height:34px;} 32 | .dk-form>form.form-horizontal>div.form-group>div{padding:0;} 33 | 34 | .dk-form-element{position:relative;} 35 | .dk-form-element>lable.valid-false, .dk-form-element>.input-group>lable.valid-false{position:absolute; top:0; right:0; bottom:0; left:0; background-color:#ff0000; opacity:0.5; border-radius:4px; line-height:34px; color:#fff; padding:0 5px; z-index:2999; border-radius:0;} 36 | .dk-form-element>input.valid-true{border-color:green;} 37 | 38 | .dk-imagegrid{width:100%; height:160px; overflow:auto;} 39 | .dk-imagegrid>.image-element{width:200px; float:left; margin-right:10px;} 40 | .dk-imagegrid>.image-element:last-child{margin:0;} 41 | .dk-imagegrid>.image-element>img{width:200px; height:150px;} 42 | 43 | .dk-search-form{height:auto; padding:10px 0; border:solid 1px #ccc;} 44 | .dk-search-form>form>.form-group{margin:15px 0;} 45 | .dk-search-form>form>.form-group:first-child{margin-top:0;} 46 | .dk-search-form>form>.form-group:last-child{margin-bottom:0;} 47 | .dk-search-form>form>.form-group>.element-group>.dk-form-element{width:50%; float:left;} 48 | 49 | .form-header{width:100%; height:38px; line-height:38px; font-size:18px; font-weight:200; color:#666666; padding:0 10px; border-bottom: solid 1px #ccc; margin-bottom:10px;} 50 | -------------------------------------------------------------------------------- /redux/middleware/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var ProgressBarPlugin = require('progress-bar-webpack-plugin'); 4 | //css样式从js文件中分离出来,需要通过命令行安装 extract-text-webpack-plugin依赖包 5 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 6 | module.exports = { 7 | entry: './src/app.js',//唯一入口文件 8 | output: {//输出目录 9 | path: path.resolve(__dirname, './dist'),//打包后的js文件存放的地方(build 后的文件) 10 | publicPath: '/dist/',//指定资源文件引用的目录(build 在内存中的位置) 11 | filename: 'bundle.js'//打包后输出的js的文件名 12 | }, 13 | module: { 14 | rules: [{ 15 | test: /\.css$/, 16 | exclude: '/node_modules/', 17 | loader: 'style-loader!css-loader?sourceMap' 18 | }, { 19 | test: /\.scss$/, 20 | exclude: /node_modules/, 21 | use: [{ 22 | loader: "style-loader" // creates style nodes from JS strings 23 | }, { 24 | loader: "css-loader" // translates CSS into CommonJS 25 | }, { 26 | loader: "sass-loader" // compiles Sass to CSS 27 | }] 28 | // loader: ExtractTextPlugin.extract("style", 'css!sass') //这里用了样式分离出来的插件,如果不想分离出来,可以直接这样写 loader:'style!css!sass' 29 | } ,{ 30 | test: /\.(js|jsx)$/, //一个匹配loaders所处理的文件的拓展名的正则表达式,这里用来匹配js和jsx文件(必须) 31 | exclude: '/node_modules/', //屏蔽不需要处理的文件(文件夹)(可选) 32 | use: ['babel-loader'] 33 | },{ 34 | test: /\.(woff|svg|eot|ttf)\??.*$/, 35 | exclude: /node_modules/, 36 | loader: 'url-loader?limit=50000&name=[path][name].[ext]' 37 | },{ 38 | test: /\.(jpe?g|png|gif|svg)$/i, 39 | use: [{ 40 | loader: 'file-loader', 41 | options: { 42 | query: { 43 | name:'assets/[name].[ext]' 44 | } 45 | } 46 | },{ 47 | loader: 'image-webpack-loader', 48 | options: { 49 | query: { 50 | mozjpeg: { 51 | progressive: true, 52 | }, 53 | gifsicle: { 54 | interlaced: true, 55 | }, 56 | optipng: { 57 | optimizationLevel: 7, 58 | } 59 | } 60 | } 61 | }] 62 | }] 63 | }, 64 | plugins: [ 65 | new webpack.HotModuleReplacementPlugin(), 66 | new ProgressBarPlugin(), 67 | new ExtractTextPlugin('styles.css') 68 | ] 69 | }; -------------------------------------------------------------------------------- /reactERP/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var ProgressBarPlugin = require('progress-bar-webpack-plugin'); 4 | //css样式从js文件中分离出来,需要通过命令行安装 extract-text-webpack-plugin依赖包 5 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 6 | module.exports = { 7 | entry: './src/app.js',//唯一入口文件 8 | output: {//输出目录 9 | path: path.resolve(__dirname, './dist'),//打包后的js文件存放的地方(build 后的文件) 10 | publicPath: '/dist/',//指定资源文件引用的目录(build 在内存中的位置) 11 | filename: 'bundle.js'//打包后输出的js的文件名 12 | }, 13 | module: { 14 | rules: [{ 15 | test: /\.css$/, 16 | exclude: '/node_modules/', 17 | loader: 'style-loader!css-loader?sourceMap' 18 | }, { 19 | test: /\.scss$/, 20 | exclude: /node_modules/, 21 | use: [{ 22 | loader: "style-loader" // creates style nodes from JS strings 23 | }, { 24 | loader: "css-loader" // translates CSS into CommonJS 25 | }, { 26 | loader: "sass-loader" // compiles Sass to CSS 27 | }] 28 | // loader: ExtractTextPlugin.extract("style", 'css!sass') //这里用了样式分离出来的插件,如果不想分离出来,可以直接这样写 loader:'style!css!sass' 29 | } ,{ 30 | test: /\.(js|jsx)$/, //一个匹配loaders所处理的文件的拓展名的正则表达式,这里用来匹配js和jsx文件(必须) 31 | exclude: '/node_modules/', //屏蔽不需要处理的文件(文件夹)(可选) 32 | use: ['babel-loader'] 33 | }, { 34 | test: /\.(woff|svg|eot|ttf)\??.*$/, 35 | exclude: /node_modules/, 36 | loader: 'url-loader?limit=80000&name=fonts/[name].[md5.hash.hex:7].[ext]' 37 | },{ 38 | test: /\.(jpe?g|png|gif|svg)$/i, 39 | use: [{ 40 | loader: 'file-loader', 41 | options: { 42 | query: { 43 | name:'assets/[name].[ext]' 44 | } 45 | } 46 | },{ 47 | loader: 'image-webpack-loader', 48 | options: { 49 | query: { 50 | mozjpeg: { 51 | progressive: true, 52 | }, 53 | gifsicle: { 54 | interlaced: true, 55 | }, 56 | optipng: { 57 | optimizationLevel: 7, 58 | } 59 | } 60 | } 61 | }] 62 | }] 63 | }, 64 | plugins: [ 65 | new webpack.HotModuleReplacementPlugin(), 66 | new ProgressBarPlugin(), 67 | new ExtractTextPlugin('styles.css') 68 | ] 69 | }; -------------------------------------------------------------------------------- /reactERP/src/components/datagrid/datagridcomponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {connect} from 'react-redux' 3 | 4 | import SpinnerComponent from '../spinner/spinner' 5 | 6 | import * as actions from './datagridaction' 7 | 8 | class DatagridComponent extends React.Component{ 9 | getKeys(item){ 10 | let cols = item ? Object.keys(item) : []; 11 | return this.props.config.cols || cols; 12 | } 13 | selectTr(item){ 14 | if(this.props.cb){ 15 | this.props.cb(item) 16 | } 17 | } 18 | componentWillMount(){ 19 | this.props.refresh(this.props.config) 20 | } 21 | render(){ 22 | let ds = this.props.dataset; 23 | let name = this.props.config.name; 24 | if(name){ 25 | ds = ds[name] ? ds[name].dataset : [] 26 | } else { 27 | ds = ds.dataset || []; 28 | } 29 | return ( 30 |
31 | 32 | 33 | 34 | { 35 | this.getKeys(ds[0]).map((key) => { 36 | return 37 | }) 38 | } 39 | 40 | 41 | 42 | { 43 | ds.map((item) => { 44 | return ( 45 | 46 | { 47 | this.getKeys(item).map((key) => { 48 | return 49 | }) 50 | } 51 | 52 | ) 53 | }) 54 | } 55 | 56 | 57 |
{key}
{item[key]}
58 | 59 |
60 | ) 61 | } 62 | } 63 | 64 | const mapStateToProps = (state) => { 65 | return { 66 | dataset: state.datagrid, 67 | show: state.datagrid.show, 68 | error: state.datagrid.error 69 | } 70 | } 71 | 72 | export default connect(mapStateToProps, actions)(DatagridComponent); -------------------------------------------------------------------------------- /reactERP/src/libs/bootstrap/datepicker/less/datepicker.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Datepicker for Bootstrap 3 | * 4 | * Copyright 2012 Stefan Petre 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | */ 9 | 10 | .datepicker { 11 | top: 0; 12 | left: 0; 13 | padding: 4px; 14 | margin-top: 1px; 15 | .border-radius(4px); 16 | &:before { 17 | content: ''; 18 | display: inline-block; 19 | border-left: 7px solid transparent; 20 | border-right: 7px solid transparent; 21 | border-bottom: 7px solid #ccc; 22 | border-bottom-color: rgba(0,0,0,.2); 23 | position: absolute; 24 | top: -7px; 25 | left: 6px; 26 | } 27 | &:after { 28 | content: ''; 29 | display: inline-block; 30 | border-left: 6px solid transparent; 31 | border-right: 6px solid transparent; 32 | border-bottom: 6px solid @white; 33 | position: absolute; 34 | top: -6px; 35 | left: 7px; 36 | } 37 | >div { 38 | display: none; 39 | } 40 | table{ 41 | width: 100%; 42 | margin: 0; 43 | } 44 | td, 45 | th{ 46 | text-align: center; 47 | width: 20px; 48 | height: 20px; 49 | .border-radius(4px); 50 | } 51 | td { 52 | &.day:hover { 53 | background: @grayLighter; 54 | cursor: pointer; 55 | } 56 | &.day.disabled { 57 | color: @grayLighter; 58 | } 59 | &.old, 60 | &.new { 61 | color: @grayLight; 62 | } 63 | &.active, 64 | &.active:hover { 65 | .buttonBackground(@btnPrimaryBackground, spin(@btnPrimaryBackground, 20)); 66 | color: #fff; 67 | text-shadow: 0 -1px 0 rgba(0,0,0,.25); 68 | } 69 | span { 70 | display: block; 71 | width: 47px; 72 | height: 54px; 73 | line-height: 54px; 74 | float: left; 75 | margin: 2px; 76 | cursor: pointer; 77 | .border-radius(4px); 78 | &:hover { 79 | background: @grayLighter; 80 | } 81 | &.active { 82 | .buttonBackground(@btnPrimaryBackground, spin(@btnPrimaryBackground, 20)); 83 | color: #fff; 84 | text-shadow: 0 -1px 0 rgba(0,0,0,.25); 85 | } 86 | &.old { 87 | color: @grayLight; 88 | } 89 | } 90 | } 91 | 92 | th { 93 | &.switch { 94 | width: 145px; 95 | } 96 | &.next, 97 | &.prev { 98 | font-size: @baseFontSize * 1.5; 99 | } 100 | } 101 | 102 | thead tr:first-child th { 103 | cursor: pointer; 104 | &:hover{ 105 | background: @grayLighter; 106 | } 107 | } 108 | /*.dow { 109 | border-top: 1px solid #ddd !important; 110 | }*/ 111 | } 112 | .input-append, 113 | .input-prepend { 114 | &.date { 115 | .add-on i { 116 | display: block; 117 | cursor: pointer; 118 | width: 16px; 119 | height: 16px; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /jsx/README.md: -------------------------------------------------------------------------------- 1 | # JSX 语法 2 | 一种特殊的 js 语法糖,可以在代码中把 html 标签当对象使用,其可以总结成以下几个特点: 3 | ### 不加任何引号 4 | 以前在 js 中使用 html 标签都是加上引号当成字符串使用,而在 jsx 语法中不用加引号,直接当对象使用 5 | ```javascript 6 | var html =

React

; 7 | ``` 8 | ### 标签一定要有对应的结束标标签或结束标识: 9 | 有时候我们在写 html 结构的时候,都没有把对应的结束标识加上,但浏览器能正常解析,但在 jsx 语法当中,则要强制写标准的 html 结构 10 | 这一段 html 标签在浏览器是能正常解析 11 | ```html 12 | 13 | ``` 14 | 这一段在 jsx 语法当中则会报错 15 | ```javascript 16 | var html = ; 17 | ``` 18 | jsx 正确写法应该是这样的 19 | ```javascript 20 | var html = ; 21 | var div =
React
; 22 | ``` 23 | ### 只能有一个根节点 24 | 在 jsx 语法当中,最顶层的结构一定只有一个节点,不能出现兄弟节点 25 | ```javascript 26 | var html = 27 |
28 |

Tom

29 |

Lucy

30 |
31 | ``` 32 | ### 不能在标签当中加注释 33 | 在 jsx 语法当中,html 标签是一个对象,是一种数据结构,而不是真实的 dom 节点,也不是字符串,所以在标签当中不能添加注释。 34 | 下面的代码是在标签当中添加了注释,所以会报错。 35 | ```javascript 36 | var html = 37 |
38 | 39 |

Tom

40 |

Lucy

41 |
42 | ``` 43 | ### jsx 语法允许 html 标签和 javascript 代码混写 44 | 在 jsx 语法当中,要在 html 标签中用到 js 代码,则用花括号({expression})括起来。 45 | ```javascript 46 | var name = "DK"; 47 | var style = {fontSize: '12px', color: 'red'}; 48 | var html = {name}; 49 | ``` 50 | 最终上面的代码将会解析成 51 | ```html 52 | DK 53 | ``` 54 | 55 | # React 使用 56 | ### React 是一个第三方的框架库,所以在使用前要先把相关的库文件引入。 57 | ```html 58 | 59 | 60 | 61 | 62 | 63 | 64 | ``` 65 | ### React 是基于 jsx 语法去实现,所以需要明确 script 的类型为 text/babel 66 | ```html 67 | 68 | ``` 69 | ### 使用 React 的核心对象和方法`ReactDOM.render`进行将 html 标签渲染到指定的容器 70 | ```html 71 | 72 |
73 |
74 |
75 | 76 | 77 | 104 | 105 | ``` 106 | [效果预览](https://dk-lan.github.io/react/jsx/jsx.html) -------------------------------------------------------------------------------- /component/src/event/README.md: -------------------------------------------------------------------------------- 1 | ## 事件和 ref 2 | 事件可以直接写到 DOM 节点,然后通过 ref 来获取 DOM 节点 3 | ```javascript 4 | import React from 'react'; 5 | import ReactDOM from 'react-dom'; 6 | 7 | class Component1 extends React.Component{ 8 | focusHandler(){ 9 | this.refs.name.focus(); 10 | } 11 | render(){ 12 | return ( 13 |
14 | 15 | 16 |
17 | ); 18 | } 19 | }; 20 | 21 | ReactDOM.render(, document.getElementById('div1')); 22 | ``` 23 | [效果预览](https://dk-lan.github.io/react/component/src/event/event.html) 24 | 25 | ## 事件对象 —— event 26 | React 在事件方法调用上默认会传一个形参`events`,该对象是一个合成事件,所以不需要担心浏览器兼容的问题。 27 | ```javascript 28 | import React from 'react'; 29 | import ReactDOM from 'react-dom'; 30 | 31 | class Component1 extends React.Component{ 32 | submit(e){ 33 | e.target.style.color = 'red' 34 | } 35 | render(){ 36 | return 37 | } 38 | } 39 | 40 | ReactDOM.render( 41 | , 42 | document.getElementById('app') 43 | ) 44 | ``` 45 | 46 | ## 事件 —— this 指针 47 | 在所有的事件当中,首先都要弄明白 `this` 指向哪里。而 React 事件中(如上面的案例)默认的 `this` 都是 `undefined`,为了 this 指针能正确指回组件对象本身,通常可以用下面几种方法。 48 | ### 事件定义使用箭头函数 49 | ```javascript 50 | class Component1 extends React.Component{ 51 | submit = (e) => { 52 | console.log(this) 53 | e.target.style.color = 'red' 54 | } 55 | render(){ 56 | return 57 | } 58 | } 59 | ``` 60 | ### 事件调用时使用用箭头函数 61 | ```javascript 62 | class Component1 extends React.Component{ 63 | submit(e){ 64 | console.log(this) 65 | e.target.style.color = 'red' 66 | } 67 | render(){ 68 | return this.submit(e)}/> 69 | } 70 | } 71 | ``` 72 | ### 构造函数中使用 bind 73 | ```javascript 74 | class Component1 extends React.Component{ 75 | constructor(props){ 76 | super(props) 77 | this.submit = this.submit.bind(this); 78 | } 79 | submit(e){ 80 | console.log(this) 81 | e.target.style.color = 'red' 82 | } 83 | render(){ 84 | return 85 | } 86 | } 87 | ``` 88 | ### 事件调用时用 bind 89 | ```javascript 90 | class Component1 extends React.Component{ 91 | submit(e){ 92 | console.log(this) 93 | e.target.style.color = 'red' 94 | } 95 | render(){ 96 | return 97 | } 98 | } 99 | ``` 100 | 101 | ## 事件传参数 102 | ### 事件调用时使用用箭头函数 103 | ```javascript 104 | class Component1 extends React.Component{ 105 | submit(e, n){ 106 | console.log(this, n) 107 | e.target.style.color = 'red' 108 | } 109 | render(){ 110 | return this.submit(e, 100)}/> 111 | } 112 | } 113 | ``` 114 | ### 事件调用时用 bind 115 | ```javascript 116 | submit(n, e){ 117 | console.log(n) 118 | e.target.style.color = 'red' 119 | } 120 | render(){ 121 | return 122 | } 123 | } 124 | ``` 125 | -------------------------------------------------------------------------------- /redux/combineReducers/README.md: -------------------------------------------------------------------------------- 1 | ## Redux 跨组件通信之入门篇 —— combineReducers 2 | ### 结构 3 | - component1 4 | - actions.js 5 | - reducer.js 6 | - component1.js 7 | - component2 8 | - actions.js 9 | - reducer.js 10 | - component.js 11 | - redux 12 | - store.js 13 | 14 | ### 组件 Component1 15 | #### action.js 16 | ```javascript 17 | export default { 18 | increment(){ 19 | return { 20 | type: "+" 21 | } 22 | }, 23 | decrement(){ 24 | return { 25 | type: '-' 26 | } 27 | } 28 | } 29 | ``` 30 | #### reducer.js 31 | ```javascript 32 | export default (state = 0, action) => { 33 | switch(action.type){ 34 | case '+': 35 | return state + 1; 36 | case '-': 37 | return state - 1; 38 | default: 39 | return state; 40 | } 41 | } 42 | ``` 43 | #### component.js 44 | ```javascript 45 | import React, {Component} from 'react' 46 | import Actions from './actions' 47 | import Reducer from './reducer' 48 | 49 | import store from '../../redux/configStore' 50 | 51 | import Component2 from '../cp2/cp2' 52 | 53 | export default class Component1 extends Component{ 54 | constructor(props){ 55 | super(props); 56 | this.state = {count: 0} 57 | } 58 | increment = () => { 59 | store.dispatch(Actions.increment()); 60 | this.setState({ 61 | count: store.getState().cp1 62 | }) 63 | } 64 | 65 | render(){ 66 | return ( 67 |
68 |

component-cp1-{store.getState().cp1}

69 | 70 | 71 |
72 | ) 73 | } 74 | } 75 | ``` 76 | 77 | ### 组件 component2 78 | #### action.js 79 | ```javascript 80 | export default { 81 | increment(){ 82 | return { 83 | type: "+" 84 | } 85 | }, 86 | decrement(){ 87 | return { 88 | type: '-' 89 | } 90 | } 91 | } 92 | ``` 93 | #### reducer.js 94 | ```javascript 95 | export default (state = 0, action) => { 96 | switch(action.type){ 97 | case '+': 98 | return state + 1; 99 | case '-': 100 | return state - 1; 101 | default: 102 | return state; 103 | } 104 | } 105 | ``` 106 | #### component.js 107 | ```javascript 108 | import React, {Component} from 'react' 109 | import Actions from './actions' 110 | import Reducer from './reducer' 111 | 112 | import store from '../../redux/configStore' 113 | 114 | export default class Component2 extends Component{ 115 | increment = () => { 116 | store.dispatch(Actions.increment()); 117 | this.setState({ 118 | count: store.getState().cp1 119 | }) 120 | } 121 | 122 | render(){ 123 | return ( 124 |
125 |

component-cp2-{store.getState().cp2}

126 |
127 | ) 128 | } 129 | } 130 | ``` 131 | 132 | ### store.js 133 | ```javascript 134 | import {createStore} from 'redux'; 135 | import { combineReducers } from 'redux'; 136 | import cp1 from '../components/cp1/reducer' 137 | import cp2 from '../components/cp2/reducer' 138 | 139 | const rootReducer = combineReducers({ 140 | cp1, 141 | cp2 142 | }); 143 | 144 | const store = createStore(rootReducer) 145 | 146 | export default store; 147 | ``` 148 | 149 | ## 小结 150 | 通过共同调用`store`已实现两个组件之间的通信 151 | - 多个组件之间,每个组件都有单独的`actions`和`reducer` 152 | - 多个组件之间的`reducer`通过`redux.combineReducers`来进行合并得到一个`rootReducer`,最后用`createStore`来完成`store`的创建生成。 153 | - 在 View 层通过`store.getState()`得到的是`rootReducer`后的对象`{cp1: 0, cp2: 0}` 154 | - `store.dispath`会同时改变`rootReducer`里面的属性`cp1`和`cp2`,因为触发了`reducer`,而且两个`action.type`都是一样的,所以同时修改 155 | - 如果想做到单独修改`rootReducer`,则需要变改不同组件`action.type` 156 | - 为了`action.type`能统一管理,可以派生出多一个层`constants`,后面的案例会用到这个层 157 | -------------------------------------------------------------------------------- /component/src/form/README.md: -------------------------------------------------------------------------------- 1 | # 表单 2 | React 是个单向数据流的框架,所以在表单元素与其它 DOM 元素有所不同,而且和双向绑定的框架在操作上也有很大不一样。所以在这里单独拿出来说。 3 | 4 | ## 输入受控 5 | ```javascript 6 | import React from 'react' 7 | import ReactDOM from 'react-dom' 8 | 9 | class Component1 extends React.Component{ 10 | constructor(props){ 11 | super(props) 12 | this.state = { 13 | text: 'Hello React' 14 | } 15 | } 16 | render(){ 17 | return ( 18 |
19 |

20 |

21 |

22 |
23 | ) 24 | } 25 | } 26 | 27 | ReactDOM.render(, document.getElementById('div1')); 28 | ``` 29 | 这个案例说明了在 React 在表单元素因单向数据流所以在 value 给定后就无法再次修改,所以需要配合 `onChange` 事件来完成。所以上面的案例应该是这样的 30 | ```javascript 31 | class Component1 extends React.Component{ 32 | constructor(props){ 33 | super(props) 34 | this.state = { 35 | text: 'Hello React' 36 | } 37 | } 38 | change = (e) => { 39 | this.setState({text: e.target.value}) 40 | } 41 | render(){ 42 | return ( 43 |
44 |

45 |

46 |

47 |
48 | ) 49 | } 50 | } 51 | ``` 52 | [效果预览](https://dk-lan.github.io/react/component/src/form/input.html) 53 | 54 | ## textarea 元素 55 | 在普通 HTML 中,`textarea` 元素是节点文本值 56 | ```html 57 | 60 | ``` 61 | 但在 React 中,该元素需要使用 `value` 属性。 62 | ```javascript 63 | class Component1 extends React.Component{ 64 | constructor(props){ 65 | super(props) 66 | this.state = { 67 | text: 'Hello React' 68 | } 69 | } 70 | change = (e) => { 71 | this.setState({text: e.target.value}) 72 | } 73 | render(){ 74 | return ( 75 |
76 |