├── .DS_Store ├── .github └── FUNDING.yml ├── .gitignore ├── .project ├── CASE.md ├── DOM └── 类名切换.html ├── README.md ├── build ├── JSXTransformer.js ├── angular.js ├── babel.js ├── browser.min.js ├── jquery.js ├── jquery.min.js ├── react-0.13.4.js ├── react-0.13.4.min.js ├── react-0.14.0.js ├── react-dom-0.14.0.js ├── react-dom.js ├── react-with-addons.js ├── react-with-addons.min.js ├── react.js └── redux.js ├── cms ├── .babelrc ├── app │ ├── action.js │ ├── components │ │ ├── about.jsx │ │ ├── basic.jsx │ │ ├── home.jsx │ │ └── topics.jsx │ ├── main.js │ └── reducer.js ├── build │ ├── bundle.js │ └── index.html ├── package.json └── webpack.config.js ├── css └── weui.css ├── lol ├── .babelrc ├── app │ ├── action.js │ ├── components │ │ ├── about.jsx │ │ ├── basic.jsx │ │ ├── home.jsx │ │ └── topics.jsx │ ├── main.js │ └── reducer.js ├── build │ ├── bundle.js │ └── index.html ├── package.json └── webpack.config.js ├── react+webpack+react-router+redux ├── .babelrc ├── app │ ├── action.js │ ├── components │ │ ├── about.jsx │ │ ├── basic.jsx │ │ ├── home.jsx │ │ └── topics.jsx │ ├── main.js │ └── reducer.js ├── build │ ├── bundle.js │ └── index.html ├── package.json └── webpack.config.js ├── react+webpack+react-router ├── .babelrc ├── app │ ├── components │ │ ├── index │ │ │ ├── indexA.jsx │ │ │ ├── indexB.jsx │ │ │ └── skill.jsx │ │ ├── productBox.jsx │ │ └── wscats.jsx │ └── main.js ├── build │ ├── bundle.js │ └── index.html ├── package.json └── webpack.config.js ├── react+webpack ├── .babelrc ├── app │ ├── components │ │ ├── index │ │ │ ├── indexA.jsx │ │ │ └── indexB.jsx │ │ ├── productBox.jsx │ │ ├── root.jsx │ │ └── wscats.jsx │ ├── main.js │ ├── routes.js │ └── store.js ├── build │ ├── bundle.js │ └── index.html ├── package.json └── webpack.config.js ├── react-router └── index.html ├── react ├── .DS_Store ├── component │ └── src │ │ ├── app.es5.js │ │ ├── app.es6.js │ │ ├── communication │ │ ├── README.md │ │ └── communication.html │ │ ├── define │ │ ├── README.md │ │ ├── define.es5.js │ │ ├── define.es6.js │ │ ├── define.html │ │ ├── 函数组件.html │ │ └── 类组件和props.html │ │ ├── event │ │ ├── README.md │ │ └── event.html │ │ ├── form │ │ ├── README.md │ │ ├── input.html │ │ └── 表单.html │ │ ├── lifecycle │ │ ├── README.md │ │ ├── lifecycle.html │ │ └── 生命周期.html │ │ ├── props │ │ └── props.html │ │ ├── render │ │ ├── README.md │ │ └── condition-rendering.html │ │ ├── state │ │ ├── README.md │ │ ├── es5-state.html │ │ ├── es6-state.html │ │ └── setState.html │ │ └── style │ │ └── README.md ├── create-react-app │ └── README.md ├── js │ ├── ReactRouter.js │ ├── ReactRouter.min.js │ ├── babel.js │ ├── browser.min.js │ ├── react-addons-update.js │ ├── react-dom.js │ ├── react-router.js │ ├── react-router.min.js │ └── react.js ├── jsx │ ├── 1.helloworld.html │ ├── 10.v-if.html │ ├── 11.v-on.html │ ├── 2.vue.html │ ├── 3.jsx.html │ ├── 4.函数式编程.html │ ├── 5.v-for.html │ ├── 6.v-show.html │ ├── 7.v-bind:xxx.html │ ├── 8.v-html.html │ ├── 9.xss.html │ ├── README.md │ ├── handsome.jpeg │ └── test.html ├── react-devtool │ └── README.md ├── reactERP │ ├── .DS_Store │ ├── .babelrc │ ├── dist │ │ ├── 46661d6d65debc63884004fed6e37e5c.svg │ │ ├── bundle.js │ │ ├── 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 │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── app.js │ │ ├── components │ │ │ ├── app │ │ │ │ └── app.js │ │ │ ├── cnode │ │ │ │ ├── cnode.js │ │ │ │ └── cnode.scss │ │ │ ├── datagrid │ │ │ │ ├── datagridaction.js │ │ │ │ ├── datagridcomponent.js │ │ │ │ ├── datagridconstants.js │ │ │ │ └── datagridreducer.js │ │ │ ├── home │ │ │ │ ├── header │ │ │ │ │ ├── header.js │ │ │ │ │ └── header.scss │ │ │ │ ├── home.js │ │ │ │ ├── home.scss │ │ │ │ └── nav │ │ │ │ │ ├── nav.js │ │ │ │ │ └── nav.scss │ │ │ ├── login │ │ │ │ ├── login.js │ │ │ │ └── login.scss │ │ │ ├── modal │ │ │ │ ├── modal.css │ │ │ │ └── modalcomponent.js │ │ │ └── spinner │ │ │ │ ├── spinner.js │ │ │ │ └── spinner.scss │ │ ├── libs │ │ │ ├── bootstrap │ │ │ │ ├── css │ │ │ │ │ ├── bootstrap-main-responsive.css │ │ │ │ │ ├── bootstrap-main.css │ │ │ │ │ ├── bootstrap-theme-light.css │ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ │ ├── bootstrap-theme.min.css │ │ │ │ │ ├── bootstrap.css │ │ │ │ │ ├── bootstrap.global.css │ │ │ │ │ ├── bootstrap.min.css │ │ │ │ │ └── hp.min.css │ │ │ │ ├── datepicker │ │ │ │ │ ├── css │ │ │ │ │ │ └── datepicker.css │ │ │ │ │ ├── js │ │ │ │ │ │ └── bootstrap-datepicker.js │ │ │ │ │ └── less │ │ │ │ │ │ └── datepicker.less │ │ │ │ ├── fonts │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ │ └── js │ │ │ │ │ ├── bootstrap.js │ │ │ │ │ ├── bootstrap.main.js │ │ │ │ │ └── bootstrap.min.js │ │ │ ├── common │ │ │ │ ├── common.js │ │ │ │ ├── common.scss │ │ │ │ └── global.scss │ │ │ ├── font-awesome │ │ │ │ ├── css │ │ │ │ │ ├── font-awesome.css │ │ │ │ │ └── font-awesome.min.css │ │ │ │ ├── font-awesome.css │ │ │ │ ├── font-awesome.min.css │ │ │ │ ├── fonts │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ ├── less │ │ │ │ │ ├── animated.less │ │ │ │ │ ├── bordered-pulled.less │ │ │ │ │ ├── core.less │ │ │ │ │ ├── fixed-width.less │ │ │ │ │ ├── font-awesome.less │ │ │ │ │ ├── icons.less │ │ │ │ │ ├── larger.less │ │ │ │ │ ├── list.less │ │ │ │ │ ├── mixins.less │ │ │ │ │ ├── path.less │ │ │ │ │ ├── rotated-flipped.less │ │ │ │ │ ├── stacked.less │ │ │ │ │ └── variables.less │ │ │ │ └── scss │ │ │ │ │ ├── _animated.scss │ │ │ │ │ ├── _bordered-pulled.scss │ │ │ │ │ ├── _core.scss │ │ │ │ │ ├── _fixed-width.scss │ │ │ │ │ ├── _icons.scss │ │ │ │ │ ├── _larger.scss │ │ │ │ │ ├── _list.scss │ │ │ │ │ ├── _mixins.scss │ │ │ │ │ ├── _path.scss │ │ │ │ │ ├── _rotated-flipped.scss │ │ │ │ │ ├── _stacked.scss │ │ │ │ │ ├── _variables.scss │ │ │ │ │ └── font-awesome.scss │ │ │ └── imgs │ │ │ │ ├── green.jpg │ │ │ │ ├── red.jpg │ │ │ │ └── yellow.jpg │ │ ├── modules │ │ │ ├── cp │ │ │ │ ├── cp.css │ │ │ │ └── cp.js │ │ │ ├── login │ │ │ │ ├── Login.scss │ │ │ │ ├── LoginAction.js │ │ │ │ ├── LoginComponent.js │ │ │ │ ├── LoginConstants.js │ │ │ │ └── LoginReducer.js │ │ │ └── order │ │ │ │ ├── orderAction.js │ │ │ │ ├── orderComponent.js │ │ │ │ ├── orderConstant.js │ │ │ │ └── orderReducer.js │ │ ├── redux │ │ │ ├── configStore.js │ │ │ ├── middleware.js │ │ │ └── rootReducer.js │ │ ├── router │ │ │ └── index.js │ │ └── utils │ │ │ ├── HttpClient.js │ │ │ └── ajaxMiddleware.js │ └── webpack.config.js ├── redux │ ├── README.md │ ├── combineReducers │ │ └── README.md │ ├── connetProvider │ │ └── README.md │ └── middleware │ │ ├── .babelrc │ │ ├── README.md │ │ ├── dist │ │ ├── 46661d6d65debc63884004fed6e37e5c.svg │ │ ├── bundle.js │ │ └── src │ │ │ └── libs │ │ │ └── font-awesome │ │ │ └── fonts │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── index.html │ │ ├── package.json │ │ ├── src │ │ ├── app.js │ │ ├── components │ │ │ ├── cnode │ │ │ │ └── cnode.js │ │ │ ├── datagrid │ │ │ │ ├── datagridaction.js │ │ │ │ ├── datagridcomponent.js │ │ │ │ ├── datagridconstants.js │ │ │ │ └── datagridreducer.js │ │ │ └── spinner │ │ │ │ ├── spinner.js │ │ │ │ └── spinner.scss │ │ ├── redux │ │ │ ├── middleware.js │ │ │ ├── rootReducer.js │ │ │ └── store.js │ │ └── utils │ │ │ └── HttpClient.js │ │ └── webpack.config.js ├── router │ ├── README.md │ ├── index.html │ └── params.html ├── router4 │ └── README.md ├── summery │ ├── .DS_Store │ ├── images │ │ ├── defect-of-mvc.png │ │ ├── flux.png │ │ ├── mobx-flow.png │ │ ├── mvc-base.png │ │ ├── redux.png │ │ └── structure-sharing.png │ └── summery.md └── webpack │ ├── README.md │ └── what-is-webpack.png ├── redux ├── demo1 │ ├── angular+redux.html │ ├── index.html │ └── react+redux.html ├── demo2 │ └── index.html └── js │ ├── redux.js │ └── vue.js ├── 事件委托 └── 事件委托.html ├── 双向数据绑定 ├── demo.html ├── 传递函数到函数体.html └── 遍历列表的事件监听和传参.html ├── 图灵机器人 ├── index.html └── test.json ├── 生命周期 └── index.html ├── 组件 ├── 1.weui │ ├── components │ │ ├── xheader.jsx │ │ ├── xpanel.jsx │ │ └── xsearch.jsx │ ├── css │ │ ├── base.css │ │ └── weui.css │ ├── index.html │ └── qqnews.json ├── props传对象.html ├── setState更改状态.html ├── 类式组件和函数组件组合.html ├── 组件添加状态.html ├── 组件的this指向.html └── 选项卡.html └── 遍历 └── 遍历.html /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/.DS_Store -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | Thanks 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | react-demo 4 | 5 | 6 | 7 | 8 | 9 | com.aptana.ide.core.unifiedBuilder 10 | 11 | 12 | 13 | 14 | 15 | com.aptana.projects.webnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /CASE.md: -------------------------------------------------------------------------------- 1 | # react-tutorial 2 | 3 | |DEMO|DEMO| 4 | |-|-| 5 | |[react实现图灵机器人](https://wscats.github.io/react-tutorial/图灵机器人/index.html)|[react双向数据绑定](https://wscats.github.io/react-tutorial/双向数据绑定/demo.html)| 6 | |[react传递参数到函数体](https://wscats.github.io/react-tutorial/双向数据绑定/传递函数到函数体.html)|[react遍历列表的事件监听和传参](https://wscats.github.io/react-tutorial/双向数据绑定/遍历列表的事件监听和传参.html)| 7 | 8 | 9 | ## Redux 10 | |DEMO|DEMO| 11 | |-|-| 12 | |[原生rudux实例](https://wscats.github.io/react-tutorial/redux/demo1/index.html)|[vue+rudux实例](https://wscats.github.io/react-tutorial/redux/demo2/index.html)| 13 | |[react+redux组件通信](https://wscats.github.io/react-tutorial/redux/demo1/react+redux.html)|[angular+redux组件通信](https://wscats.github.io/react-tutorial/redux/demo1/angular+redux.html)| 14 | 15 | ## Route 16 | |DEMO|DEMO| 17 | |-|-| 18 | |[路由嵌套和组件传参](https://wscats.github.io/react-tutorial/react+webpack+react-router/build/index.html)|| 19 | 20 | ## DOM 21 | |DEMO|DEMO| 22 | |-|-| 23 | |[遍历数组](https://wscats.github.io/react-tutorial/遍历/遍历.html)|[类名切换](https://wscats.github.io/react-tutorial/DOM/类名切换.html)| 24 | 25 | ## Component 26 | |DEMO|DEMO| 27 | |-|-| 28 | |[组件Props传对象](https://wscats.github.io/react-tutorial/组件/props传对象.html)|[类式组件和函数组件组合](https://wscats.github.io/react-tutorial/组件/类式组件和函数组件组合.html)| 29 | |[组件添加状态](https://wscats.github.io/react-tutorial/组件/组件添加状态.html)|[组件的this指向](https://wscats.github.io/react-tutorial/组件/组件的this指向.html)| 30 | |[setState更改状态](https://wscats.github.io/react-tutorial/组件/setState更改状态.html)|[组件化开发案例](https://wscats.github.io/react-tutorial/组件/1.weui/index.html)| 31 | |[选项卡](https://wscats.github.io/react-tutorial/组件/选项卡.html)|| 32 | -------------------------------------------------------------------------------- /DOM/类名切换.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 92 | 93 | -------------------------------------------------------------------------------- /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/wscats/react-tutorial/tree/master/react/jsx) 10 | - [组件定义](https://github.com/wscats/react-tutorial/tree/master/react/component/src/define) 11 | - [组件渲染](https://github.com/wscats/react-tutorial/tree/master/react/component/src/render) 12 | - [组件事件](https://github.com/wscats/react-tutorial/tree/master/react/component/src/event) 13 | - [state](https://github.com/wscats/react-tutorial/tree/master/react/component/src/state) 14 | - [样式绑定](https://github.com/wscats/react-tutorial/tree/master/react/component/src/style) 15 | - [表单](https://github.com/wscats/react-tutorial/tree/master/react/component/src/form) 16 | - [组件通信](https://github.com/wscats/react-tutorial/tree/master/react/component/src/communication) 17 | - [生命周期](https://github.com/wscats/react-tutorial/tree/master/react/component/src/lifecycle) 18 | - [模块化(webpack)](https://github.com/wscats/react-tutorial/tree/master/react/webpack) 19 | - [脚手架(create-react-app)](https://github.com/wscats/react-tutorial/tree/master/react/create-react-app) 20 | - [调试工具(react-dev-tool)](https://github.com/wscats/react-tutorial/tree/master/react/react-devtool) 21 | - [路由(3.0)](https://github.com/wscats/react-tutorial/tree/master/react/router)[和(4.0)](https://github.com/wscats/react-tutorial/tree/master/react/router4) 22 | - Redux 23 | - [Redux 简介和简单实现](https://github.com/wscats/react-tutorial/tree/master/react/redux) 24 | - [Redux 跨组件通信之入门篇 —— combineReducers](https://github.com/wscats/react-tutorial/tree/master/react/redux/combineReducers) 25 | - [Redux 跨组件通信之进阶篇 —— Provider 和 connect](https://github.com/wscats/react-tutorial/tree/master/react/redux/connetProvider) 26 | - [Redux 跨组件通信之高级篇 —— 中间件](https://github.com/wscats/react-tutorial/tree/master/react/redux/middleware) 27 | - [项目应用](https://wscats.github.io/react-tutorial/react/reactERP/index.html#/login) 28 | - [其他案例](https://github.com/Wscats/react-tutorial/blob/master/CASE.md) 29 | - [纲要总结](https://github.com/Wscats/react-tutorial/blob/master/react/summery/summery.md) 30 | 31 | # 题外话 32 | 33 | 这份教程是综合了[Y.Pig](https://github.com/Wscats/react-tutorial)和[DK](https://github.com/dk-lan/react)的内容,因为代码和文档比较多,整理中如有疏漏或者错误,可以在 Issues 中提出,多多谅解,希望对你们有帮助,如果你喜欢可以点个 Star 或者 Fork ,谢谢~ -------------------------------------------------------------------------------- /build/react-dom-0.14.0.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ReactDOM v0.14.0 3 | * 4 | * Copyright 2013-2015, 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 | // 18 | 19 | -------------------------------------------------------------------------------- /cms/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "babel-core": "^6.24.1", 4 | "babel-loader": "^7.0.0", 5 | "babel-preset-es2015": "^6.24.1", 6 | "babel-preset-react": "^6.24.1", 7 | "less-loader": "^4.0.3", 8 | "react": "^15.5.4", 9 | "react-dom": "^15.5.4", 10 | "react-router-dom": "^4.1.1", 11 | "style-loader": "^0.16.1", 12 | "url-loader": "^0.5.8", 13 | "webpack": "^2.4.1", 14 | "webpack-dev-server": "^2.4.2" 15 | }, 16 | "dependencies": { 17 | "history": "^4.6.1", 18 | "react-bootstrap": "^0.31.0", 19 | "react-redux": "^5.0.5", 20 | "react-router-config": "^1.0.0-beta.3", 21 | "redux": "^3.6.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cms/webpack.config.js: -------------------------------------------------------------------------------- 1 | //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 2 | module.exports = { //注意这里是exports不是export 3 | devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map 4 | entry: __dirname + "/app/main.js", //唯一入口文件 5 | output: { //输出目录 6 | path: __dirname + "/build", //打包后的js文件存放的地方 7 | filename: 'bundle.js', //打包后的js文件名 8 | }, 9 | module: { 10 | loaders: [{ 11 | test: /\.js[x]?$/, //匹配到js或jsx文件后 使用 babel-loader 来处理 12 | exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选) 13 | loader: 'babel-loader' 14 | //npm install babel-loader 15 | //npm install babel-core 16 | }, { 17 | test: /\.css$/, 18 | loader: 'style-loader!css-loader' 19 | }, { 20 | test: /\.less$/, 21 | loader: 'style-loader!css-loader!less-loader' 22 | }, { 23 | test: /\.(png|jpg)$/, 24 | loader: 'url-loader?limit=25000' 25 | }] 26 | }, 27 | devServer: { 28 | contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录) 29 | historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html 30 | inline: true, //设置为true,当源文件改变时会自动刷新页面 31 | port: 12345, //设置默认监听端口,如果省略,默认为"8080" 32 | } 33 | }; -------------------------------------------------------------------------------- /lol/.babelrc: -------------------------------------------------------------------------------- 1 | //.babelrc 2 | { 3 | "presets": [ 4 | "react", 5 | "es2015" 6 | ] 7 | } -------------------------------------------------------------------------------- /lol/app/action.js: -------------------------------------------------------------------------------- 1 | export function increaseAction() { 2 | return {type: 'increase'}; 3 | } 4 | 5 | export function multiAction() { 6 | return {type: 'multi'}; 7 | } 8 | -------------------------------------------------------------------------------- /lol/app/components/about.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Jumbotron, 4 | Checkbox, 5 | Radio, 6 | ControlLabel, 7 | FormControl, 8 | Button 9 | } from 'react-bootstrap'; 10 | class About extends React.Component { 11 | render() { 12 | return ( 13 |
14 | 15 |

Hello, world!

16 |

This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.

17 |

18 | 19 |

20 |
21 |
22 | ) 23 | } 24 | } 25 | module.exports = About; 26 | -------------------------------------------------------------------------------- /lol/app/components/home.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | import { 3 | Grid, 4 | Row, 5 | Col, 6 | Table, 7 | ButtonToolbar, 8 | Button 9 | } from 'react-bootstrap'; 10 | class ProductBox extends React.Component { 11 | render() { 12 | return ( 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | 39 |
#First NameLast NameUsername
1MarkOtto 32 | 33 | 34 | 35 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 | ) 51 | } 52 | } 53 | module.exports = ProductBox; 54 | -------------------------------------------------------------------------------- /lol/app/components/topics.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {BrowserRouter as Router, Route, Link} from 'react-router-dom' 3 | 4 | import {connect} from 'react-redux'; 5 | 6 | import {increaseAction, multiAction} from '../action.js'; 7 | 8 | const Topic = ({match}) => ( 9 |
10 |

{match.params.topicId}

11 |
12 | ) 13 | class Topics extends React.Component { 14 | render() { 15 | const {value, onIncreaseClick} = this.props; 16 | return ( 17 |
18 |

主题列表

19 |

{value}

20 | 21 | 38 | 39 | ( 40 |

请选择一个主题。

41 | )}/> 42 |
43 | ) 44 | } 45 | } 46 | 47 | // Map Redux state to component props 48 | function mapStateToProps(state) { 49 | return {value: state.count} 50 | } 51 | 52 | // Map Redux actions to component props 53 | function mapDispatchToProps(dispatch) { 54 | return { 55 | onIncreaseClick: () => { 56 | //可以触发多个 57 | dispatch(increaseAction()) 58 | dispatch(multiAction()) 59 | } 60 | } 61 | } 62 | 63 | // Connected Component 让Topics也连接上store 64 | module.exports = connect(mapStateToProps, mapDispatchToProps)(Topics); 65 | -------------------------------------------------------------------------------- /lol/app/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Basic from "./components/basic.jsx"; 4 | 5 | //redux 6 | import {Provider, connect} from 'react-redux'; 7 | import {createStore} from 'redux'; 8 | 9 | //模块化action,方便在组件中调用 10 | import {increaseAction, multiAction} from './action.js'; 11 | //模块化reducer 12 | import counter from './reducer.js'; 13 | 14 | // Store 15 | const store = createStore(counter); 16 | 17 | // Action 18 | // const increaseAction = { 19 | // type: 'increase' 20 | // } 21 | // 22 | // const multiAction = { 23 | // type: 'multi' 24 | // } 25 | 26 | // Reducer 27 | // function counter(state = { 28 | // count: 0 29 | // }, action) { 30 | // const count = state.count 31 | // switch (action.type) { 32 | // case 'increase': 33 | // return { 34 | // count: count + 2 35 | // } 36 | // case 'multi': 37 | // return { 38 | // count: count * 2 39 | // } 40 | // default: 41 | // return state 42 | // } 43 | // } 44 | 45 | // 放在Basic入面connect 46 | // // Map Redux state to component props 47 | // function mapStateToProps(state) { 48 | // return {value: state.count} 49 | // } 50 | // 51 | // // Map Redux actions to component props 52 | // function mapDispatchToProps(dispatch) { 53 | // return { 54 | // onIncreaseClick: () => { 55 | // //可以触发多个 56 | // dispatch(increaseAction()) 57 | // dispatch(multiAction()) 58 | // } 59 | // } 60 | // } 61 | 62 | // Connected Component 63 | //const App = connect(mapStateToProps, mapDispatchToProps)(Basic) 64 | 65 | ReactDOM.render(( 66 | 67 | 68 | 69 | ), document.getElementById('root')) 70 | -------------------------------------------------------------------------------- /lol/app/reducer.js: -------------------------------------------------------------------------------- 1 | export default function counter(state = { 2 | count: 0 3 | }, action) { 4 | const count = state.count 5 | switch (action.type) { 6 | case 'increase': 7 | return { 8 | count: count + 2 9 | } 10 | case 'multi': 11 | return { 12 | count: count * 2 13 | } 14 | default: 15 | return state 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lol/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | React Test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /lol/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "babel-core": "^6.24.1", 4 | "babel-loader": "^7.0.0", 5 | "babel-preset-es2015": "^6.24.1", 6 | "babel-preset-react": "^6.24.1", 7 | "less-loader": "^4.0.3", 8 | "react": "^15.5.4", 9 | "react-dom": "^15.5.4", 10 | "react-router-dom": "^4.1.1", 11 | "style-loader": "^0.16.1", 12 | "url-loader": "^0.5.8", 13 | "webpack": "^2.4.1", 14 | "webpack-dev-server": "^2.4.2" 15 | }, 16 | "dependencies": { 17 | "history": "^4.6.1", 18 | "react-bootstrap": "^0.31.0", 19 | "react-redux": "^5.0.5", 20 | "react-router-config": "^1.0.0-beta.3", 21 | "redux": "^3.6.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lol/webpack.config.js: -------------------------------------------------------------------------------- 1 | //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 2 | module.exports = { //注意这里是exports不是export 3 | devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map 4 | entry: __dirname + "/app/main.js", //唯一入口文件 5 | output: { //输出目录 6 | path: __dirname + "/build", //打包后的js文件存放的地方 7 | filename: 'bundle.js', //打包后的js文件名 8 | }, 9 | module: { 10 | loaders: [{ 11 | test: /\.js[x]?$/, //匹配到js或jsx文件后 使用 babel-loader 来处理 12 | exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选) 13 | loader: 'babel-loader' 14 | //npm install babel-loader 15 | //npm install babel-core 16 | }, { 17 | test: /\.css$/, 18 | loader: 'style-loader!css-loader' 19 | }, { 20 | test: /\.less$/, 21 | loader: 'style-loader!css-loader!less-loader' 22 | }, { 23 | test: /\.(png|jpg)$/, 24 | loader: 'url-loader?limit=25000' 25 | }] 26 | }, 27 | devServer: { 28 | contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录) 29 | historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html 30 | inline: true, //设置为true,当源文件改变时会自动刷新页面 31 | port: 12345, //设置默认监听端口,如果省略,默认为"8080" 32 | } 33 | }; -------------------------------------------------------------------------------- /react+webpack+react-router+redux/.babelrc: -------------------------------------------------------------------------------- 1 | //.babelrc 2 | { 3 | "presets": [ 4 | "react", 5 | "es2015" 6 | ] 7 | } -------------------------------------------------------------------------------- /react+webpack+react-router+redux/app/action.js: -------------------------------------------------------------------------------- 1 | export function increaseAction() { 2 | return {type: 'increase'}; 3 | } 4 | 5 | export function multiAction() { 6 | return {type: 'multi'}; 7 | } 8 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/app/components/about.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {ButtonGroup, Button} from 'react-bootstrap'; 3 | class About extends React.Component { 4 | render() { 5 | return ( 6 |
7 |

关于

8 | 9 | 10 | 11 | 12 |
Hello World!
13 |
14 | ) 15 | } 16 | } 17 | module.exports = About; 18 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/app/components/home.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | class ProductBox extends React.Component { 3 | render() { 4 | return( 5 |
Hello World!
6 | ) 7 | } 8 | } 9 | module.exports = ProductBox; -------------------------------------------------------------------------------- /react+webpack+react-router+redux/app/components/topics.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {BrowserRouter as Router, Route, Link} from 'react-router-dom' 3 | 4 | import {connect} from 'react-redux'; 5 | 6 | import {increaseAction, multiAction} from '../action.js'; 7 | 8 | const Topic = ({match}) => ( 9 |
10 |

{match.params.topicId}

11 |
12 | ) 13 | class Topics extends React.Component { 14 | render() { 15 | const {value, onIncreaseClick} = this.props; 16 | return ( 17 |
18 |

主题列表

19 |

{value}

20 | 21 | 38 | 39 | ( 40 |

请选择一个主题。

41 | )}/> 42 |
43 | ) 44 | } 45 | } 46 | 47 | // Map Redux state to component props 48 | function mapStateToProps(state) { 49 | return {value: state.count} 50 | } 51 | 52 | // Map Redux actions to component props 53 | function mapDispatchToProps(dispatch) { 54 | return { 55 | onIncreaseClick: () => { 56 | //可以触发多个 57 | dispatch(increaseAction()) 58 | dispatch(multiAction()) 59 | } 60 | } 61 | } 62 | 63 | // Connected Component 让Topics也连接上store 64 | module.exports = connect(mapStateToProps, mapDispatchToProps)(Topics); 65 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/app/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Basic from "./components/basic.jsx"; 4 | 5 | //redux 6 | import {Provider, connect} from 'react-redux'; 7 | import {createStore} from 'redux'; 8 | 9 | //模块化action,方便在组件中调用 10 | import {increaseAction, multiAction} from './action.js'; 11 | //模块化reducer 12 | import counter from './reducer.js'; 13 | 14 | // Store 15 | const store = createStore(counter); 16 | 17 | // Action 18 | // const increaseAction = { 19 | // type: 'increase' 20 | // } 21 | // 22 | // const multiAction = { 23 | // type: 'multi' 24 | // } 25 | 26 | // Reducer 27 | // function counter(state = { 28 | // count: 0 29 | // }, action) { 30 | // const count = state.count 31 | // switch (action.type) { 32 | // case 'increase': 33 | // return { 34 | // count: count + 2 35 | // } 36 | // case 'multi': 37 | // return { 38 | // count: count * 2 39 | // } 40 | // default: 41 | // return state 42 | // } 43 | // } 44 | 45 | // 放在Basic入面connect 46 | // // Map Redux state to component props 47 | // function mapStateToProps(state) { 48 | // return {value: state.count} 49 | // } 50 | // 51 | // // Map Redux actions to component props 52 | // function mapDispatchToProps(dispatch) { 53 | // return { 54 | // onIncreaseClick: () => { 55 | // //可以触发多个 56 | // dispatch(increaseAction()) 57 | // dispatch(multiAction()) 58 | // } 59 | // } 60 | // } 61 | 62 | // Connected Component 63 | //const App = connect(mapStateToProps, mapDispatchToProps)(Basic) 64 | 65 | ReactDOM.render(( 66 | 67 | 68 | 69 | ), document.getElementById('root')) 70 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/app/reducer.js: -------------------------------------------------------------------------------- 1 | export default function counter(state = { 2 | count: 0 3 | }, action) { 4 | const count = state.count 5 | switch (action.type) { 6 | case 'increase': 7 | return { 8 | count: count + 2 9 | } 10 | case 'multi': 11 | return { 12 | count: count * 2 13 | } 14 | default: 15 | return state 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React Test 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "babel-core": "^6.24.1", 4 | "babel-loader": "^7.0.0", 5 | "babel-preset-es2015": "^6.24.1", 6 | "babel-preset-react": "^6.24.1", 7 | "less-loader": "^4.0.3", 8 | "react": "^15.5.4", 9 | "react-dom": "^15.5.4", 10 | "react-router-dom": "^4.1.1", 11 | "style-loader": "^0.16.1", 12 | "url-loader": "^0.5.8", 13 | "webpack": "^2.4.1", 14 | "webpack-dev-server": "^2.4.2" 15 | }, 16 | "dependencies": { 17 | "history": "^4.6.1", 18 | "react-bootstrap": "^0.31.0", 19 | "react-redux": "^5.0.5", 20 | "react-router-config": "^1.0.0-beta.3", 21 | "redux": "^3.6.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /react+webpack+react-router+redux/webpack.config.js: -------------------------------------------------------------------------------- 1 | //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 2 | module.exports = { //注意这里是exports不是export 3 | devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map 4 | entry: __dirname + "/app/main.js", //唯一入口文件 5 | output: { //输出目录 6 | path: __dirname + "/build", //打包后的js文件存放的地方 7 | filename: 'bundle.js', //打包后的js文件名 8 | }, 9 | module: { 10 | loaders: [{ 11 | test: /\.js[x]?$/, //匹配到js或jsx文件后 使用 babel-loader 来处理 12 | exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选) 13 | loader: 'babel-loader' 14 | //npm install babel-loader 15 | //npm install babel-core 16 | }, { 17 | test: /\.css$/, 18 | loader: 'style-loader!css-loader' 19 | }, { 20 | test: /\.less$/, 21 | loader: 'style-loader!css-loader!less-loader' 22 | }, { 23 | test: /\.(png|jpg)$/, 24 | loader: 'url-loader?limit=25000' 25 | }] 26 | }, 27 | devServer: { 28 | contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录) 29 | historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html 30 | inline: true, //设置为true,当源文件改变时会自动刷新页面 31 | port: 12345, //设置默认监听端口,如果省略,默认为"8080" 32 | } 33 | }; -------------------------------------------------------------------------------- /react+webpack+react-router/.babelrc: -------------------------------------------------------------------------------- 1 | //.babelrc 2 | { 3 | "presets": [ 4 | "react", 5 | "es2015" 6 | ] 7 | } -------------------------------------------------------------------------------- /react+webpack+react-router/app/components/index/indexA.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | //新版本的写法 推荐 3 | class IndexA extends React.Component { 4 | render() { 5 | return( 6 |
Index A
7 | ) 8 | } 9 | } 10 | module.exports = IndexA; -------------------------------------------------------------------------------- /react+webpack+react-router/app/components/index/indexB.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | //新版本的写法 推荐 3 | class IndexB extends React.Component { 4 | render() { 5 | return( 6 |
Index B
7 | ) 8 | } 9 | } 10 | module.exports = IndexB; -------------------------------------------------------------------------------- /react+webpack+react-router/app/components/index/skill.jsx: -------------------------------------------------------------------------------- 1 | //var React = require('react'); 2 | import React from 'react'; 3 | import PropTypes from 'prop-types'; 4 | //新版本的写法 推荐 5 | class Skill extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | // 设置 initial state 9 | this.state = { 10 | text: props.initialValue || 'Hello Wscats' 11 | }; 12 | // ES6 类中函数必须手动绑定 13 | this.handleChange = this.handleChange.bind(this); 14 | } 15 | componentDidMount() { 16 | console.log(this.props.match) 17 | } 18 | handleChange(event) { 19 | console.log(this) 20 | this.setState({ 21 | text: event.target.value 22 | }); 23 | } 24 | render() { 25 | return( 26 |
27 |
sKill
28 |
29 | Type something: 30 | 31 |

{this.state.text}

32 |
33 |
34 | ) 35 | } 36 | } 37 | Skill.propTypes = { 38 | //定义传入props中的属性各种类型 39 | initialValue: PropTypes.string.isRequired//PropTypes.string 40 | }; 41 | Skill.defaultProps = { 42 | //组件默认的props对象 43 | initialValue: 'Hello Oaoafly' 44 | }; 45 | module.exports = Skill; -------------------------------------------------------------------------------- /react+webpack+react-router/app/components/productBox.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | //旧版本的写法,会有警告 3 | /*var ProductBox = React.createClass({ 4 | render: function() { 5 | return( 6 |
7 | Hello World! 8 |
9 | ); 10 | } 11 | });*/ 12 | //新版本的写法 推荐 13 | class ProductBox extends React.Component { 14 | render() { 15 | return( 16 |
Hello World!
17 | ) 18 | } 19 | } 20 | module.exports = ProductBox; -------------------------------------------------------------------------------- /react+webpack+react-router/app/components/wscats.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDom = require('react-dom'); 3 | //引入skill组件 4 | var Skill = require('./index/skill.jsx'); 5 | import { 6 | BrowserRouter as Router, 7 | Route, 8 | Link 9 | } from 'react-router-dom' 10 | const Topic = () => ( 11 |
12 |
Topic
13 |
14 | ) 15 | const About = ({match}) => ( 16 |
17 |
About
18 |

ID: {match.params.id}

19 |
20 | ) 21 | //新版本的写法 推荐 22 | class Wscats extends React.Component { 23 | render() { 24 | return( 25 |
26 |
Wscats
27 |
28 |

主题列表

29 | 46 | 47 | 48 | 49 |
50 |
51 | ) 52 | } 53 | } 54 | module.exports = Wscats; -------------------------------------------------------------------------------- /react+webpack+react-router/app/main.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDom = require('react-dom'); 3 | //import { Router, Route, Switch } from 'react-router' 4 | import { 5 | BrowserRouter as Router, 6 | Route, 7 | Link 8 | } from 'react-router-dom' 9 | 10 | var AppComponent = require('./components/productBox.jsx'); 11 | var Wscats = require('./components/wscats.jsx'); 12 | var IndexA = require('./components/index/indexA.jsx'); 13 | var IndexB = require('./components/index/indexB.jsx'); 14 | /*ReactDom.render( 15 | 16 | , document.getElementById('content') 17 | );*/ 18 | 19 | ReactDom.render(( 20 | 21 | {/*Route 组件就是用于配置路由, path 属性用于配置路径, component 就是对应的 React Component*/} 22 | {/*rouer只能有一个子标签,所以用div包起来*/} 23 |
24 |
    25 |
  • /
  • 26 |
  • index
  • 27 |
28 | 29 | 30 | 31 |
32 |
33 | ), document.getElementById('content')) -------------------------------------------------------------------------------- /react+webpack+react-router/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Test 6 | 7 | 8 | 9 |
10 | 11 | -------------------------------------------------------------------------------- /react+webpack+react-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "babel-core": "^6.24.1", 4 | "babel-loader": "^7.0.0", 5 | "babel-preset-es2015": "^6.24.1", 6 | "babel-preset-react": "^6.24.1", 7 | "less-loader": "^4.0.3", 8 | "prop-types": "^15.5.10", 9 | "react": "^15.5.4", 10 | "react-dom": "^15.5.4", 11 | "react-router-dom": "^4.1.1", 12 | "style-loader": "^0.16.1", 13 | "url-loader": "^0.5.8", 14 | "webpack": "^2.4.1", 15 | "webpack-dev-server": "^2.4.2" 16 | }, 17 | "dependencies": { 18 | "redux": "^3.6.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /react+webpack+react-router/webpack.config.js: -------------------------------------------------------------------------------- 1 | //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 2 | module.exports = { //注意这里是exports不是export 3 | devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map 4 | entry: __dirname + "/app/main.js", //唯一入口文件 5 | output: { //输出目录 6 | path: __dirname + "/build", //打包后的js文件存放的地方 7 | filename: 'bundle.js', //打包后的js文件名 8 | }, 9 | module: { 10 | loaders: [{ 11 | test: /\.js[x]?$/, //匹配到js或jsx文件后 使用 babel-loader 来处理 12 | exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选) 13 | loader: 'babel-loader' 14 | //npm install babel-loader 15 | //npm install babel-core 16 | }, { 17 | test: /\.css$/, 18 | loader: 'style-loader!css-loader' 19 | }, { 20 | test: /\.less$/, 21 | loader: 'style-loader!css-loader!less-loader' 22 | }, { 23 | test: /\.(png|jpg)$/, 24 | loader: 'url-loader?limit=25000' 25 | }] 26 | }, 27 | devServer: { 28 | contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录) 29 | historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html 30 | inline: true, //设置为true,当源文件改变时会自动刷新页面 31 | port: 8080, //设置默认监听端口,如果省略,默认为"8080" 32 | } 33 | }; -------------------------------------------------------------------------------- /react+webpack/.babelrc: -------------------------------------------------------------------------------- 1 | //.babelrc 2 | { 3 | "presets": [ 4 | "react", 5 | "es2015" 6 | ] 7 | } -------------------------------------------------------------------------------- /react+webpack/app/components/index/indexA.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | //新版本的写法 推荐 3 | class IndexA extends React.Component { 4 | render() { 5 | return( 6 |
Index A
7 | ) 8 | } 9 | } 10 | module.exports = IndexA; -------------------------------------------------------------------------------- /react+webpack/app/components/index/indexB.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | //新版本的写法 推荐 3 | class IndexB extends React.Component { 4 | render() { 5 | return( 6 |
Index B
7 | ) 8 | } 9 | } 10 | module.exports = IndexB; -------------------------------------------------------------------------------- /react+webpack/app/components/productBox.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | //旧版本的写法,会有警告 3 | /*var ProductBox = React.createClass({ 4 | render: function() { 5 | return( 6 |
7 | Hello World! 8 |
9 | ); 10 | } 11 | });*/ 12 | //新版本的写法 推荐 13 | class ProductBox extends React.Component { 14 | render() { 15 | return( 16 |
Hello World!
17 | ) 18 | } 19 | } 20 | module.exports = ProductBox; -------------------------------------------------------------------------------- /react+webpack/app/components/root.jsx: -------------------------------------------------------------------------------- 1 | //var React = require('react'); 2 | import React, { Component } from 'react'; 3 | import { 4 | BrowserRouter as Router, 5 | Route, 6 | Link 7 | } from 'react-router-dom'; 8 | import { matchRoutes, renderRoutes } from 'react-router-config'; 9 | //新版本的写法 推荐 10 | //class Wscats extends React.Component { 11 | class Wscats extends Component { 12 | render() { 13 | return( 14 |
15 |

Root

16 | home index 17 | {/* child routes won't render without this */} 18 | {renderRoutes(this.props.route.routes)} 19 | {console.log(this)} 20 |
21 | ) 22 | } 23 | } 24 | module.exports = Wscats; -------------------------------------------------------------------------------- /react+webpack/app/components/wscats.jsx: -------------------------------------------------------------------------------- 1 | //var React = require('react'); 2 | import React, { Component } from 'react'; 3 | var routes = require("../routes.js"); 4 | import { 5 | BrowserRouter as Router, 6 | Route, 7 | Link 8 | } from 'react-router-dom'; 9 | import { matchRoutes, renderRoutes } from 'react-router-config'; 10 | 11 | var IndexA = require('./index/indexA.jsx'); 12 | var IndexB = require('./index/indexB.jsx'); 13 | console.log(routes) 14 | //新版本的写法 推荐 15 | //class Wscats extends React.Component { 16 | class Wscats extends Component { 17 | render() { 18 | return( 19 |
20 |
Wscats
21 | childA childB 22 | {renderRoutes(this.props.route.routes)} 23 | {console.log(this.props.route.routes)} 24 | {console.log(routes)} 25 |
26 | ) 27 | } 28 | } 29 | module.exports = Wscats; -------------------------------------------------------------------------------- /react+webpack/app/main.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDom = require('react-dom'); 3 | //npm install --save react-router-config 4 | import { matchRoutes, renderRoutes } from 'react-router-config' 5 | import { 6 | BrowserRouter as Router, 7 | Route, 8 | Link 9 | } from 'react-router-dom' 10 | 11 | 12 | var routes = require("./routes.js"); 13 | matchRoutes(routes, '/index'); 14 | console.log(routes) 15 | //默认路由 16 | const branch = matchRoutes(routes, '/index') 17 | ReactDom.render(( 18 | 19 | {renderRoutes(routes)} 20 | 21 | ), document.getElementById('content')) -------------------------------------------------------------------------------- /react+webpack/app/routes.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | import { matchRoutes, renderRoutes } from 'react-router-config'; 3 | import { 4 | BrowserRouter as Router, 5 | Route, 6 | Link 7 | } from 'react-router-dom'; 8 | 9 | var AppComponent = require('./components/productBox.jsx'); 10 | var Wscats = require('./components/wscats.jsx'); 11 | var IndexA = require('./components/index/indexA.jsx'); 12 | var IndexB = require('./components/index/indexB.jsx'); 13 | var Root = require('./components/root.jsx') 14 | //根组件 15 | /*const Root = ({route}) => ( 16 |
17 |

Root

18 | home index 19 | {renderRoutes(route.routes)} 20 | {console.log(route)} 21 |
22 | )*/ 23 | 24 | const routes = [ 25 | { component: Root, 26 | routes: [ 27 | { path: '/', 28 | exact: true, 29 | component: AppComponent 30 | }, 31 | { path: '/index', 32 | component: Wscats, 33 | routes: [ 34 | { path: '/childA', 35 | component: IndexA 36 | }, 37 | { path: '/childB', 38 | component: IndexB 39 | } 40 | ] 41 | } 42 | ] 43 | } 44 | ] 45 | module.exports = routes; -------------------------------------------------------------------------------- /react+webpack/app/store.js: -------------------------------------------------------------------------------- 1 | import { 2 | applyMiddleware, 3 | createStore 4 | } from "redux" 5 | import logger from "redux-logger" 6 | import thunk from "redux-thunk" 7 | import promise from "redux-promise-middleware" 8 | import reducer from "./reducers" 9 | const middleware = applyMiddleware(promise(), thunk, logger()) 10 | export default createStore(reducer, middleware) -------------------------------------------------------------------------------- /react+webpack/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Test 6 | 7 | 8 | 9 |
10 | 11 | -------------------------------------------------------------------------------- /react+webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "babel-core": "^6.24.1", 4 | "babel-loader": "^7.0.0", 5 | "babel-preset-es2015": "^6.24.1", 6 | "babel-preset-react": "^6.24.1", 7 | "less-loader": "^4.0.3", 8 | "react": "^15.5.4", 9 | "react-dom": "^15.5.4", 10 | "style-loader": "^0.16.1", 11 | "url-loader": "^0.5.8", 12 | "webpack": "^2.4.1", 13 | "webpack-dev-server": "^2.4.2" 14 | }, 15 | "dependencies": { 16 | "history": "^4.6.1", 17 | "react-router-config": "^1.0.0-beta.3", 18 | "redux": "^3.6.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /react+webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | //__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 2 | module.exports = { //注意这里是exports不是export 3 | devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map 4 | entry: __dirname + "/app/main.js", //唯一入口文件 5 | output: { //输出目录 6 | path: __dirname + "/build", //打包后的js文件存放的地方 7 | filename: 'bundle.js', //打包后的js文件名 8 | }, 9 | module: { 10 | loaders: [{ 11 | test: /\.js[x]?$/, //匹配到js或jsx文件后 使用 babel-loader 来处理 12 | exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选) 13 | loader: 'babel-loader' 14 | //npm install babel-loader 15 | //npm install babel-core 16 | }, { 17 | test: /\.css$/, 18 | loader: 'style-loader!css-loader' 19 | }, { 20 | test: /\.less$/, 21 | loader: 'style-loader!css-loader!less-loader' 22 | }, { 23 | test: /\.(png|jpg)$/, 24 | loader: 'url-loader?limit=25000' 25 | }] 26 | }, 27 | devServer: { 28 | contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录) 29 | historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html 30 | inline: true, //设置为true,当源文件改变时会自动刷新页面 31 | port: 12345, //设置默认监听端口,如果省略,默认为"8080" 32 | } 33 | }; -------------------------------------------------------------------------------- /react-router/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 菜鸟教程 React 实例 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /react/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/.DS_Store -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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')); -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/component/src/define/函数组件.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 47 | 48 | -------------------------------------------------------------------------------- /react/component/src/define/类组件和props.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 54 | 55 | -------------------------------------------------------------------------------- /react/component/src/event/event.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | React-Component-event 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 34 | 35 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/component/src/state/es5-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 | -------------------------------------------------------------------------------- /react/component/src/state/es6-state.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /react/component/src/state/setState.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 | 18 | 19 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /react/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 | ``` -------------------------------------------------------------------------------- /react/create-react-app/README.md: -------------------------------------------------------------------------------- 1 | # 脚手架 2 | 3 | 以系统管理员的身份,安装该脚手架全局命令 4 | ```bash 5 | npm install create-react-app -g 6 | ``` 7 | 8 | 你就会在全局命令行里面拥有一个`create-react-app`命令,可以用以下命令检查是否安装成功 9 | ```bash 10 | create-react-app -V 11 | ``` 12 | 13 | 创建第一个项目,如果安装不成功可以考虑换这两个尝试一次`yarn`和`cnpm` 14 | ```bash 15 | create-react-app [项目名字] 16 | create-react-app my-app //例如这样 17 | ``` 18 | 19 | 启动项目 20 | ```bash 21 | cd my-app 22 | npm start //或者 npm run start 23 | ``` 24 | 25 | 在浏览器里面,查看该地址 26 | ```bash 27 | http://localhost:3000/ 28 | ``` 29 | 30 | ```bash 31 | public 单页面应用的主页(ico,index.html) 32 | src 开发文件夹(组件,自定义模块,样式,模板) 33 | ``` 34 | 35 | React 和 Vue 的脚手架都是基于 webpack 的 36 | 37 | 其他具体内容也可以参考[creact react app的官方文档](https://github.com/facebook/create-react-app) -------------------------------------------------------------------------------- /react/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 | // 15 | 16 | 17 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /react/jsx/10.v-if.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 33 | 34 | -------------------------------------------------------------------------------- /react/jsx/11.v-on.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | 18 | 35 | 36 | -------------------------------------------------------------------------------- /react/jsx/2.vue.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 | 12 |
13 | 14 | 34 | 35 | -------------------------------------------------------------------------------- /react/jsx/3.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 | -------------------------------------------------------------------------------- /react/jsx/4.函数式编程.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | 18 | 34 | 35 | -------------------------------------------------------------------------------- /react/jsx/5.v-for.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | 18 | 60 | 61 | -------------------------------------------------------------------------------- /react/jsx/6.v-show.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 | 18 | 36 | 37 | -------------------------------------------------------------------------------- /react/jsx/7.v-bind:xxx.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 16 |
17 | 18 |
19 | 20 | 21 | 22 | 23 | 40 | 41 | -------------------------------------------------------------------------------- /react/jsx/8.v-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 25 | 26 | -------------------------------------------------------------------------------- /react/jsx/9.xss.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /react/jsx/handsome.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/jsx/handsome.jpeg -------------------------------------------------------------------------------- /react/jsx/test.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | 6 | 7 | 34 | -------------------------------------------------------------------------------- /react/react-devtool/README.md: -------------------------------------------------------------------------------- 1 | # react-devtool 2 | 3 | 与 Vue 的 vue-devtool 类似 react 也有一个非常有用的调试工具叫 react-devtool,下面展示 Vue 的调试工具怎么安装,React 同理,如果能访问 Chrome 的扩展商店,则更方便,直接在商场搜索安装即可。 4 | 5 | 1. 在命令行中执行下面命令,用 git 克隆该仓库到本地,并进入 vue-devtool 6 | ```bash 7 | git clone https://github.com/vuejs/vue-devtools.git 8 | cd vue-devtool 9 | ``` 10 | 2. 安装该依赖包,你也可以使用 yarn 安装 11 | 12 | ```bash 13 | npm install 14 | ``` 15 | 16 | 3. 执行打包,生成插件 17 | ```bash 18 | npm run build 19 | ``` 20 | 21 | 4. 打开谷歌浏览器的`扩展程序`,打开右上角的`开发者模式`,点击左上角`加载已加压的扩展程序`,打开该`shells/chrome`目录,加载插件 -------------------------------------------------------------------------------- /react/reactERP/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/.DS_Store -------------------------------------------------------------------------------- /react/reactERP/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "modules": false }], 4 | "react", 5 | "latest", 6 | "stage-2" 7 | ] 8 | } 9 | 10 | -------------------------------------------------------------------------------- /react/reactERP/dist/46661d6d65debc63884004fed6e37e5c.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /react/reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].ttf -------------------------------------------------------------------------------- /react/reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/dist/fonts/fontawesome-webfont.[md5.hash.hex:7].woff -------------------------------------------------------------------------------- /react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /react/reactERP/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DK-React项目应用 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /react/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": "^7.0.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 | -------------------------------------------------------------------------------- /react/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 | ) -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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); -------------------------------------------------------------------------------- /react/reactERP/src/components/datagrid/datagridconstants.js: -------------------------------------------------------------------------------- 1 | export const Requesting = 'Requesting' 2 | export const Requested = 'Requested' 3 | export const RequestError = 'RequestError' -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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;} -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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.wscats.com
30 |
31 | ) 32 | } 33 | } 34 | 35 | export default LoginComponent -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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;} -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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 -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/reactERP/src/libs/bootstrap/css/bootstrap.global.css: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /react/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /react/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/reactERP/src/libs/common/global.scss: -------------------------------------------------------------------------------- 1 | $main-color: #1ab394; 2 | $main-color-hover: #19a085; 3 | -------------------------------------------------------------------------------- /react/reactERP/src/libs/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/reactERP/src/libs/imgs/green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/imgs/green.jpg -------------------------------------------------------------------------------- /react/reactERP/src/libs/imgs/red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/imgs/red.jpg -------------------------------------------------------------------------------- /react/reactERP/src/libs/imgs/yellow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/libs/imgs/yellow.jpg -------------------------------------------------------------------------------- /react/reactERP/src/modules/cp/cp.css: -------------------------------------------------------------------------------- 1 | .c1{ 2 | color: red; 3 | width: 100%; 4 | height: 300px; 5 | border: solid 1px red; 6 | } -------------------------------------------------------------------------------- /react/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 | // } -------------------------------------------------------------------------------- /react/reactERP/src/modules/login/Login.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/reactERP/src/modules/login/Login.scss -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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) -------------------------------------------------------------------------------- /react/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'; -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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'; -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | }) -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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.wscats.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 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | }; -------------------------------------------------------------------------------- /react/redux/middleware/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "modules": false }], 4 | "react", 5 | "latest", 6 | "stage-2" 7 | ] 8 | } 9 | 10 | -------------------------------------------------------------------------------- /react/redux/middleware/dist/46661d6d65debc63884004fed6e37e5c.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/redux/middleware/dist/src/libs/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /react/redux/middleware/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DK-中间件实现案例 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /react/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 | -------------------------------------------------------------------------------- /react/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 | ) -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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); -------------------------------------------------------------------------------- /react/redux/middleware/src/components/datagrid/datagridconstants.js: -------------------------------------------------------------------------------- 1 | export const Requesting = 'Requesting' 2 | export const Requested = 'Requested' 3 | export const RequestError = 'RequestError' -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | } -------------------------------------------------------------------------------- /react/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 | }) -------------------------------------------------------------------------------- /react/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; -------------------------------------------------------------------------------- /react/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.wscats.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 | -------------------------------------------------------------------------------- /react/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 | }; -------------------------------------------------------------------------------- /react/router/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 路由-基本用法 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 60 | 61 | -------------------------------------------------------------------------------- /react/router4/README.md: -------------------------------------------------------------------------------- 1 | # 路由 2 | 3 | 关于路由,我们得先了解,什么是单页面应用程序和多页面应用程序,因为路由是帮助我们实现单页面应用程序的关键 4 | |type|des| 5 | |-|-| 6 | |实现单页面应用程序single page application(SPA)|不刷新整个页面,永远在一个`index.html`,依靠路由切换具体的场景,首次加载大部分大部分东西,后面异步加载具体要更新的内容| 7 | |多页面应用程序|页面跳转,整体刷新,资源文件重新加载| 8 | 9 | 10 | 在[React-Router-DOM官方文档](https://reacttraining.com/react-router/web/guides/quick-start)中你会看到关于 React 路由有以下可以选装的模块 11 | 12 | |引用|作用| 13 | |-|-| 14 | |react-router|React Router 核心| 15 | |react-router-dom|用于DOM绑定的React Router| 16 | |react-router-native|用于React Native的React Router| 17 | |react-router-redux|React Router和Redux的集成| 18 | |react-router-config|静态路由配置的小助手| 19 | 20 | ## react-router和react-router-dom的区别 21 | 在React的使用中,我们一般要引入两个包,react 和 react-dom,react-router 和react-router-dom 并不是两个都要引用的 22 | 他们两个只要引用一个就行了,不同之处就是后者比前者多出了``和``这样的 DOM 类组件。 23 | 因此我们只需引用react-router-dom这个包就行了。当然,如果搭配 redux,你还需要使用 react-router-redux 或者 react-redux 24 | 25 | 那现在我们选用的是 react-router-dom,所以先安装路由模块 react-router-dom 26 | 27 | ```bash 28 | npm install react-router-dom 29 | ``` 30 | 31 | ## BrowserRouter和HashRouter 32 | 33 | **react-router4**的[官方文档](https://reacttraining.com/react-router/web/guides/quick-start)默认使用的是`BrowserRouter,BroswerRouter`是需要服务端配合的,服务端重定向到首页,`BrowserRouter`是基于html5的`pushState`和`replaceState`的,很多浏览器不支持,存在兼容性问题。所以新手推荐使用`HashRouter` 34 | 35 | 简单总结`BrowserRouter`称为浏览器路由,使用的时候是url上面不带`#`,兼容性比较差,需要后端配合,比较好看,`HashRouter`称之为哈希路由,兼容性比较高 36 | 37 | 38 | react-router-dom 有三个内置组件 39 | ```js 40 | import { HashRouter as Router , Link , Route} from "react-router-dom"; 41 | ``` 42 | `Router`的作用是让包裹的子组件产生路由场景,相当于 Vue 中的`` 43 | ```js 44 | ReactDOM.render( 45 | 46 | 47 | 48 | , document.getElementById('root')); 49 | ``` 50 | `Link`相当于``标签,提供跳转路由的功能 51 | ```html 52 | 53 | ``` 54 | Route相当于`vue-router`里面的配置参数 55 | ```html 56 | 57 | 58 | ``` 59 | 上面代码的含义为 60 | 61 | url匹配到`#/`切换到`Index`组件 62 | 63 | url匹配到`#/detail/`切换到`Detail`组件 64 | 65 | ## 嵌套路由 66 | 67 | 68 | 路由里面放路由,第一层路由`/home/`, 69 | ```html 70 | 71 | ``` 72 | 嵌套路由就是在Index组件里面在放一个``组件,当进入`/home/hot`路径时,既加载`Index`组件,也加载`Wpannel`组件 73 | ```html 74 | 75 | ``` 76 | 注意,嵌套路由的`path`是要把第一层路由的路径加上 77 | 78 | ## 编程式导航 79 | 80 | 除了使用``标签跳转路由,还可以使用路由提供给你的`this.props.history`进行跳转 81 | 82 | ## 路由传参 83 | 84 | |状态|方式| 85 | |-|-| 86 | |Route component|以this.props.match方式| 87 | |Route render|以({ match })=>()方式| 88 | |Route children|以({ match })=>()方式| 89 | |withRouter|以this.props.match方式| 90 | -------------------------------------------------------------------------------- /react/summery/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/.DS_Store -------------------------------------------------------------------------------- /react/summery/images/defect-of-mvc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/images/defect-of-mvc.png -------------------------------------------------------------------------------- /react/summery/images/flux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/images/flux.png -------------------------------------------------------------------------------- /react/summery/images/mobx-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/images/mobx-flow.png -------------------------------------------------------------------------------- /react/summery/images/mvc-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/images/mvc-base.png -------------------------------------------------------------------------------- /react/summery/images/redux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/images/redux.png -------------------------------------------------------------------------------- /react/summery/images/structure-sharing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/summery/images/structure-sharing.png -------------------------------------------------------------------------------- /react/webpack/what-is-webpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wscats/react-tutorial/85df1bf51beb4f881a4d4ce3ea612336dc203f97/react/webpack/what-is-webpack.png -------------------------------------------------------------------------------- /redux/demo1/angular+redux.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 23 | 24 |
25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 96 | 97 | -------------------------------------------------------------------------------- /redux/demo1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redux basic example 6 | 7 | 8 | 9 | 10 | 11 |
12 |

13 | Clicked: 0 times 14 | 15 | 16 | 17 | 18 |

19 |
20 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /事件委托/事件委托.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 组件添加状态 6 | 7 | 8 | 9 | 10 | 11 |
12 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /双向数据绑定/传递函数到函数体.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React Demo By Wscats 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /双向数据绑定/遍历列表的事件监听和传参.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | React Demo By Wscats 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /图灵机器人/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /图灵机器人/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "age":"Question" 3 | } 4 | -------------------------------------------------------------------------------- /生命周期/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 菜鸟教程 React 实例 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /组件/1.weui/components/xheader.jsx: -------------------------------------------------------------------------------- 1 | var Xheader = React.createClass({ 2 | render: function() { 3 | return ( 4 |
今日头条
5 | ) 6 | } 7 | }) 8 | -------------------------------------------------------------------------------- /组件/1.weui/components/xpanel.jsx: -------------------------------------------------------------------------------- 1 | let Xpanel = React.createClass({ 2 | getInitialState() { 3 | return { 4 | arr: [ 5 | "a", "b", "c" 6 | ], 7 | news: null 8 | } 9 | }, 10 | getNews() { 11 | let xmlhttp = new XMLHttpRequest(); 12 | let self = this; 13 | xmlhttp.onreadystatechange = function() { 14 | if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 15 | console.log(JSON.parse(xmlhttp.responseText)); 16 | setTimeout(() => { 17 | self.setState({ 18 | news: JSON.parse(xmlhttp.responseText) 19 | }) 20 | }, 2000) 21 | } 22 | } 23 | xmlhttp.open("GET", "https://wscats.github.io/react-tutorial/%E7%BB%84%E4%BB%B6/1.weui/qqnews.json", true); 24 | xmlhttp.send(); 25 | }, 26 | render() { 27 | return ( 28 |
67 | ) 68 | }, 69 | componentDidMount() { 70 | this.getNews() 71 | } 72 | }) 73 | -------------------------------------------------------------------------------- /组件/1.weui/components/xsearch.jsx: -------------------------------------------------------------------------------- 1 | let Xsearch = React.createClass({ 2 | getInitialState() { 3 | return {bool: false, searchText: ""} 4 | }, 5 | focusing() { 6 | this.setState({bool: true}) 7 | console.log(this.refs.input) 8 | this.refs.input.focus() 9 | }, 10 | cancelFocusing() { 11 | this.setState({bool: false}) 12 | }, 13 | getSearchText(e) { 14 | this.setState({searchText: e.target.value}) 15 | }, 16 | searchClear() { 17 | this.setState({searchText: ""}) 18 | this.refs.input.focus() 19 | }, 20 | render() { 21 | return ( 22 | 42 | ) 43 | } 44 | }) 45 | -------------------------------------------------------------------------------- /组件/1.weui/css/base.css: -------------------------------------------------------------------------------- 1 | header{ 2 | background-color: red; 3 | height: 50px; 4 | line-height: 50px; 5 | text-align: center; 6 | color: white; 7 | width: 100% 8 | } 9 | -------------------------------------------------------------------------------- /组件/1.weui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /组件/props传对象.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | props传对象 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 24 | 25 | -------------------------------------------------------------------------------- /组件/setState更改状态.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 组件添加状态 6 | 7 | 8 | 9 | 10 | 11 |
12 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /组件/类式组件和函数组件组合.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 类式组件和函数组件组合 6 | 7 | 8 | 9 | 10 | 11 |
12 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /组件/组件添加状态.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 组件添加状态 6 | 7 | 8 | 9 | 10 | 11 |
12 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /组件/组件的this指向.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 组件添加状态 6 | 7 | 8 | 9 | 10 | 11 |
12 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /遍历/遍历.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 54 | --------------------------------------------------------------------------------