├── .gitignore ├── LICENSE ├── README.md ├── cli ├── base-antd-pro │ ├── .eslintrc │ ├── .roadhogrc.mock.js │ ├── .vscode │ │ └── settings.json │ ├── .webpackrc │ ├── mock │ │ ├── .gitkeep │ │ ├── api.js │ │ ├── chart.js │ │ ├── notices.js │ │ ├── profile.js │ │ ├── rule.js │ │ └── utils.js │ ├── package.json │ ├── public │ │ └── index.html │ └── src │ │ ├── assets │ │ ├── logo.jpg │ │ └── yay.jpg │ │ ├── common │ │ ├── menu.js │ │ └── router.js │ │ ├── components │ │ ├── Authorized │ │ │ ├── Authorized.js │ │ │ ├── AuthorizedRoute.js │ │ │ ├── CheckPermissions.js │ │ │ ├── CheckPermissions.test.js │ │ │ ├── PromiseRender.js │ │ │ ├── Secured.js │ │ │ └── index.js │ │ ├── Exception │ │ │ ├── index.js │ │ │ ├── index.less │ │ │ └── typeConfig.js │ │ ├── GlobalFooter │ │ │ ├── index.js │ │ │ └── index.less │ │ ├── GlobalHeader │ │ │ ├── index.js │ │ │ └── index.less │ │ ├── HeaderSearch │ │ │ ├── index.js │ │ │ └── index.less │ │ ├── Login │ │ │ ├── LoginItem.js │ │ │ ├── LoginSubmit.js │ │ │ ├── LoginTab.js │ │ │ ├── demo │ │ │ │ └── basic.md │ │ │ ├── index.d.ts │ │ │ ├── index.js │ │ │ ├── index.less │ │ │ ├── index.md │ │ │ └── map.js │ │ ├── NoticeIcon │ │ │ ├── NoticeList.js │ │ │ ├── NoticeList.less │ │ │ ├── index.js │ │ │ └── index.less │ │ ├── PageHeader │ │ │ ├── index.js │ │ │ └── index.less │ │ ├── Result │ │ │ ├── index.js │ │ │ └── index.less │ │ └── SiderMenu │ │ │ ├── SiderMenu.js │ │ │ ├── index.js │ │ │ └── index.less │ │ ├── e2e │ │ ├── home.e2e.js │ │ └── login.e2e.js │ │ ├── index.ejs │ │ ├── index.js │ │ ├── index.less │ │ ├── layouts │ │ ├── BaseLayout.js │ │ ├── PageHeaderLayout.js │ │ ├── PageHeaderLayout.less │ │ ├── UserLayout.js │ │ └── UserLayout.less │ │ ├── models │ │ ├── error.js │ │ ├── global.js │ │ ├── login.js │ │ ├── register.js │ │ └── user.js │ │ ├── router.js │ │ ├── routes │ │ ├── Exception │ │ │ ├── 403.js │ │ │ ├── 404.js │ │ │ ├── 500.js │ │ │ ├── style.less │ │ │ └── triggerException.js │ │ ├── Result │ │ │ ├── Error.js │ │ │ ├── Success.js │ │ │ └── Success.test.js │ │ └── User │ │ │ ├── Login.js │ │ │ ├── Login.less │ │ │ ├── Register.js │ │ │ ├── Register.less │ │ │ ├── RegisterResult.js │ │ │ └── RegisterResult.less │ │ ├── services │ │ ├── api.js │ │ ├── error.js │ │ └── user.js │ │ ├── theme.js │ │ └── utils │ │ ├── Authorized.js │ │ ├── authority.js │ │ ├── request.js │ │ ├── utils.js │ │ └── utils.less └── react-antd-dva │ ├── README.md │ ├── package.json │ ├── public │ └── index.html │ └── src │ ├── assets │ ├── logo.jpg │ └── yay.jpg │ ├── common │ ├── menu.js │ └── router.js │ ├── components │ ├── Exception │ │ ├── index.js │ │ ├── index.less │ │ └── typeConfig.js │ ├── GlobalFooter │ │ ├── index.js │ │ └── index.less │ ├── GlobalHeader │ │ ├── index.js │ │ └── index.less │ ├── HeaderLogo │ │ ├── index.js │ │ └── index.less │ ├── HeaderMenu │ │ ├── index.js │ │ └── index.less │ └── HeaderSearch │ │ ├── index.js │ │ └── index.less │ ├── index.ejs │ ├── index.js │ ├── index.less │ ├── layouts │ └── BaseLayout.js │ ├── models │ └── global.js │ ├── router.js │ ├── routes │ ├── ArticleList │ │ ├── index.js │ │ └── index.less │ └── Exception │ │ └── 404.js │ ├── services │ └── example.js │ ├── theme.js │ └── utils │ ├── request.js │ └── utils.js ├── higher-demo ├── dva-antd │ ├── antd-ui │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── .roadhogrc │ │ ├── .roadhogrc.mock.js │ │ ├── package.json │ │ ├── public │ │ │ └── index.html │ │ └── src │ │ │ ├── assets │ │ │ └── yay.jpg │ │ │ ├── components │ │ │ ├── EditableTable.js │ │ │ └── EditableTable.less │ │ │ ├── index.css │ │ │ ├── index.js │ │ │ ├── router.js │ │ │ ├── routes │ │ │ ├── IndexPage.css │ │ │ └── IndexPage.js │ │ │ ├── services │ │ │ └── example.js │ │ │ └── utils │ │ │ └── request.js │ ├── login-demo │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── .roadhogrc │ │ ├── .roadhogrc.mock.js │ │ ├── package.json │ │ ├── public │ │ │ └── index.html │ │ └── src │ │ │ ├── assets │ │ │ └── yay.jpg │ │ │ ├── components │ │ │ └── Example.js │ │ │ ├── index.css │ │ │ ├── index.js │ │ │ ├── mock │ │ │ └── mock.js │ │ │ ├── models │ │ │ ├── example.js │ │ │ └── login.js │ │ │ ├── router.js │ │ │ ├── routes │ │ │ ├── IndexPage.js │ │ │ ├── IndexPage.less │ │ │ ├── Login.js │ │ │ └── Login.less │ │ │ ├── services │ │ │ ├── example.js │ │ │ └── login.js │ │ │ └── utils │ │ │ ├── config.js │ │ │ └── request.js │ ├── mockjs-demo │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── .roadhogrc │ │ ├── .roadhogrc.mock.js │ │ ├── package.json │ │ ├── public │ │ │ └── index.html │ │ └── src │ │ │ ├── assets │ │ │ └── yay.jpg │ │ │ ├── components │ │ │ ├── Example.js │ │ │ └── List.js │ │ │ ├── index.css │ │ │ ├── index.js │ │ │ ├── mock │ │ │ └── mock.js │ │ │ ├── models │ │ │ └── index.js │ │ │ ├── router.js │ │ │ ├── routes │ │ │ ├── IndexPage.css │ │ │ └── IndexPage.js │ │ │ ├── services │ │ │ └── example.js │ │ │ └── utils │ │ │ └── request.js │ └── todo-list │ │ ├── .editorconfig │ │ ├── .eslintrc │ │ ├── .gitignore │ │ ├── .roadhogrc │ │ ├── .roadhogrc.mock.js │ │ ├── mock │ │ └── .gitkeep │ │ ├── package.json │ │ ├── public │ │ └── index.html │ │ └── src │ │ ├── assets │ │ └── yay.jpg │ │ ├── components │ │ ├── Add.js │ │ ├── Example.js │ │ └── List.js │ │ ├── index.css │ │ ├── index.js │ │ ├── models │ │ ├── add.js │ │ ├── example.js │ │ └── list.js │ │ ├── router.js │ │ ├── routes │ │ ├── IndexPage.css │ │ ├── IndexPage.js │ │ ├── List.css │ │ └── List.js │ │ ├── services │ │ └── example.js │ │ └── utils │ │ └── request.js ├── react-all │ └── react-all-demo │ │ ├── .babelrc │ │ ├── README.md │ │ ├── dist │ │ ├── api │ │ │ └── user.json │ │ ├── bundle.js │ │ └── index.html │ │ ├── package.json │ │ ├── src │ │ ├── component │ │ │ └── Hello │ │ │ │ └── Hello.js │ │ ├── index.js │ │ ├── pages │ │ │ ├── Counter │ │ │ │ └── Counter.js │ │ │ ├── Home │ │ │ │ └── Home.js │ │ │ ├── Page1 │ │ │ │ ├── Page1.css │ │ │ │ └── Page1.js │ │ │ └── UserInfo │ │ │ │ └── UserInfo.js │ │ ├── redux │ │ │ ├── actions │ │ │ │ ├── counter.js │ │ │ │ └── userInfo.js │ │ │ ├── build.js │ │ │ ├── reducers.js │ │ │ ├── reducers │ │ │ │ ├── counter.js │ │ │ │ └── userInfo.js │ │ │ ├── store.js │ │ │ └── testRedux.js │ │ └── router │ │ │ └── router.js │ │ └── webpack.dev.config.js └── redux │ └── todolist │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json │ └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── components │ ├── AddTodo.js │ ├── Footer.js │ ├── Todo.js │ └── TodoList.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── redux │ ├── actions.js │ └── reducers.js │ └── registerServiceWorker.js ├── middle-demo ├── comment-app │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ └── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── Comment.js │ │ ├── CommentInput.js │ │ ├── CommentList.js │ │ ├── index.css │ │ ├── index.js │ │ └── registerServiceWorker.js └── react表单详解 │ ├── 1、不可控组件实例.html │ ├── 2、可控组件实例.html │ ├── 3、表单元素实例.html │ ├── 4、bind复用.html │ ├── 5、name复用.html │ ├── 6、不可控的自定义组件.html │ └── 7、可控的自定义组件.html └── primer-demo ├── README.md ├── React教程 ├── 1.React 第一个实例 │ └── index.html ├── 2.React JSX │ ├── jsx-1:多html嵌套.html │ ├── jsx-2.js │ ├── jsx-2:jsx独立文件.html │ ├── jsx-3:使用JavaScript表达式.html │ ├── jsx-4:css样式.html │ ├── jsx-5:注释.html │ ├── jsx-6:数组.html │ ├── jsx-7:渲染html标签.html │ └── jsx-8:react组件初窥.html ├── 3.react 组件 │ ├── component-1:第一个组件.html │ ├── component-2:向组件传递参数.html │ └── component-3:复合组件.html ├── 4.react State │ └── state-1:第一个实例.html ├── 5.React Props │ ├── props-1:使用 Props .html │ ├── props-2:默认props.html │ ├── props-3:组合使用 state 和 props.html │ └── props-4:Props 验证.html └── README.md ├── react 编程思想 └── 1.一个简单的html.html └── reactjs 来源 ├── 1.传统写法.html ├── 2.结构复用.html ├── 3.简单的组件化.html ├── 4.状态改变自动更新.html ├── 5.抽象公共组件类.html ├── 6.添加 props.html └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | 3 | node_modules/ 4 | 5 | .code/ 6 | 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # testing 12 | /coverage 13 | 14 | # production 15 | /build 16 | 17 | # misc 18 | .DS_Store 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CFshuming 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-demo-gather 2 | 3 | react demo合集。有自己写的也有各大教程的demo。如果非原创,都会注明出处,如有侵权请及时与我联系。 4 | 5 | ## 目录介绍 6 | 7 | - primer-demo : 初级demo目录,适合初学者, 8 | 9 | - React教程 : 整理自菜鸟教程,代码有过改动,代码里有知识点详解(待补充),没有复杂的语法。 10 | - reactjs 来源 : 整理自 reactjs 小书。 11 | - react 编程思想 : 从源头实现 react。 12 | 13 | - middle-demo : 中级demo目录,适合有一定基础的人 14 | 15 | - react表单详解 : 讲了表单的一些元素,已经可控组件和不可控组件的编写。 16 | - comment-app : 使用 create-react-app 搭建的一个评论小 demo。 17 | 18 | 19 | - higher-demo : 高级demo目录,比较完整的demo,大型小型都有(目前我自己在写一些小demo) 20 | 21 | - dva-antd : 基于dva 和 antd 的一些项目,目前主要在学这个 22 | 23 | - todo-list : 大家都知道的 todo list,界面有点丑,没有优化 24 | - mockjs-demo : 使用mockjs的小demo 25 | - login-demo : 登录验证及退出的demo(登录写完,登出还没写) 26 | 27 | - antd-ui : 默认的ui不怎么够用,针对需要,会写一些复杂的ui组件(进行中)。 28 | 29 | - react-all : react 全家桶项目 30 | - react-all-demo : react 全家桶小 demo 31 | 32 | - cli: 一些脚手架 33 | - base-antd-pro:删除了 antd-pro 中非必须的组件,简化了项目。 34 | - react-antd-dva:从 antd-pro 修改的,上中下结构的项目。 35 | 36 | -------------------------------------------------------------------------------- /cli/base-antd-pro/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "plugins": ["compat"], 5 | "env": { 6 | "browser": true, 7 | "node": true, 8 | "es6": true, 9 | "mocha": true, 10 | "jest": true, 11 | "jasmine": true 12 | }, 13 | "rules": { 14 | "generator-star-spacing": [0], 15 | "consistent-return": [0], 16 | "react/forbid-prop-types": [0], 17 | "react/jsx-filename-extension": [1, { "extensions": [".js"] }], 18 | "global-require": [1], 19 | "import/prefer-default-export": [0], 20 | "react/jsx-no-bind": [0], 21 | "react/prop-types": [0], 22 | "react/prefer-stateless-function": [0], 23 | "react/jsx-wrap-multilines": ["error", { 24 | "declaration": "parens-new-line", 25 | "assignment": "parens-new-line", 26 | "return": "parens-new-line", 27 | "arrow": "parens-new-line", 28 | "condition": "parens-new-line", 29 | "logical": "parens-new-line", 30 | "prop": "ignore" 31 | }], 32 | "no-else-return": [0], 33 | "no-restricted-syntax": [0], 34 | "import/no-extraneous-dependencies": [0], 35 | "no-use-before-define": [0], 36 | "jsx-a11y/no-static-element-interactions": [0], 37 | "jsx-a11y/no-noninteractive-element-interactions": [0], 38 | "jsx-a11y/click-events-have-key-events": [0], 39 | "jsx-a11y/anchor-is-valid": [0], 40 | "no-nested-ternary": [0], 41 | "arrow-body-style": [0], 42 | "import/extensions": [0], 43 | "no-bitwise": [0], 44 | "no-cond-assign": [0], 45 | "import/no-unresolved": [0], 46 | "comma-dangle": ["error", { 47 | "arrays": "always-multiline", 48 | "objects": "always-multiline", 49 | "imports": "always-multiline", 50 | "exports": "always-multiline", 51 | "functions": "ignore" 52 | }], 53 | "object-curly-newline": [0], 54 | "function-paren-newline": [0], 55 | "no-restricted-globals": [0], 56 | "require-yield": [1], 57 | "compat/compat": "error" 58 | }, 59 | "parserOptions": { 60 | "ecmaFeatures": { 61 | "experimentalObjectRestSpread": true 62 | } 63 | }, 64 | "settings": { 65 | "polyfills": ["fetch", "promises"] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /cli/base-antd-pro/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true 3 | } -------------------------------------------------------------------------------- /cli/base-antd-pro/.webpackrc: -------------------------------------------------------------------------------- 1 | { 2 | "entry": "src/index.js", 3 | "extraBabelPlugins": [ 4 | "transform-decorators-legacy", 5 | ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": true }] 6 | ], 7 | "env": { 8 | "development": { 9 | "extraBabelPlugins": [ 10 | "dva-hmr" 11 | ] 12 | } 13 | }, 14 | "ignoreMomentLocale": true, 15 | "theme": "./src/theme.js", 16 | "html": { 17 | "template": "./src/index.ejs" 18 | }, 19 | "publicPath": "/", 20 | "disableDynamicImport": true, 21 | "hash": true 22 | } 23 | -------------------------------------------------------------------------------- /cli/base-antd-pro/mock/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/cli/base-antd-pro/mock/.gitkeep -------------------------------------------------------------------------------- /cli/base-antd-pro/mock/utils.js: -------------------------------------------------------------------------------- 1 | export const imgMap = { 2 | user: 'https://gw.alipayobjects.com/zos/rmsportal/UjusLxePxWGkttaqqmUI.png', 3 | a: 'https://gw.alipayobjects.com/zos/rmsportal/ZrkcSjizAKNWwJTwcadT.png', 4 | b: 'https://gw.alipayobjects.com/zos/rmsportal/KYlwHMeomKQbhJDRUVvt.png', 5 | c: 'https://gw.alipayobjects.com/zos/rmsportal/gabvleTstEvzkbQRfjxu.png', 6 | d: 'https://gw.alipayobjects.com/zos/rmsportal/jvpNzacxUYLlNsHTtrAD.png', 7 | }; 8 | 9 | // refers: https://www.sitepoint.com/get-url-parameters-with-javascript/ 10 | export function getUrlParams(url) { 11 | const d = decodeURIComponent; 12 | let queryString = url ? url.split('?')[1] : window.location.search.slice(1); 13 | const obj = {}; 14 | if (queryString) { 15 | queryString = queryString.split('#')[0]; // eslint-disable-line 16 | const arr = queryString.split('&'); 17 | for (let i = 0; i < arr.length; i += 1) { 18 | const a = arr[i].split('='); 19 | let paramNum; 20 | const paramName = a[0].replace(/\[\d*\]/, (v) => { 21 | paramNum = v.slice(1, -1); 22 | return ''; 23 | }); 24 | const paramValue = typeof (a[1]) === 'undefined' ? true : a[1]; 25 | if (obj[paramName]) { 26 | if (typeof obj[paramName] === 'string') { 27 | obj[paramName] = d([obj[paramName]]); 28 | } 29 | if (typeof paramNum === 'undefined') { 30 | obj[paramName].push(d(paramValue)); 31 | } else { 32 | obj[paramName][paramNum] = d(paramValue); 33 | } 34 | } else { 35 | obj[paramName] = d(paramValue); 36 | } 37 | } 38 | } 39 | return obj; 40 | } 41 | 42 | export default { 43 | getUrlParams, 44 | imgMap, 45 | }; 46 | -------------------------------------------------------------------------------- /cli/base-antd-pro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fx-blog-admin", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "cross-env DISABLE_ESLINT=true roadhog dev", 7 | "build": "roadhog build", 8 | "lint": "eslint --ext .js src test", 9 | "precommit": "npm run lint" 10 | }, 11 | "dependencies": { 12 | "@babel/polyfill": "^7.0.0-beta.36", 13 | "antd": "^3.2.0", 14 | "babel-plugin-import": "^1.6.3", 15 | "classnames": "^2.2.5", 16 | "dva": "^2.1.0", 17 | "dva-loading": "^1.0.4", 18 | "enquire-js": "^0.1.1", 19 | "fastclick": "^1.0.6", 20 | "highlight.js": "^9.12.0", 21 | "lodash": "^4.17.4", 22 | "lodash-decorators": "^4.4.1", 23 | "marked": "^0.3.12", 24 | "moment": "^2.19.1", 25 | "qs": "^6.5.0", 26 | "rc-drawer-menu": "^0.5.0", 27 | "react": "^16.2.0", 28 | "react-container-query": "^0.9.1", 29 | "react-document-title": "^2.0.3", 30 | "react-dom": "^16.2.0", 31 | "react-fittext": "^1.0.0", 32 | "url-polyfill": "^1.0.10" 33 | }, 34 | "devDependencies": { 35 | "babel-eslint": "^8.1.2", 36 | "babel-plugin-dva-hmr": "^0.4.1", 37 | "babel-plugin-import": "^1.6.3", 38 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 39 | "cross-env": "^5.1.1", 40 | "cross-port-killer": "^1.0.1", 41 | "eslint": "^4.14.0", 42 | "eslint-config-airbnb": "^16.0.0", 43 | "eslint-plugin-babel": "^4.0.0", 44 | "eslint-plugin-compat": "^2.1.0", 45 | "eslint-plugin-import": "^2.8.0", 46 | "eslint-plugin-jsx-a11y": "^6.0.3", 47 | "eslint-plugin-markdown": "^1.0.0-beta.6", 48 | "eslint-plugin-react": "^7.0.1", 49 | "husky": "^0.12.0", 50 | "mockjs": "^1.0.1-beta3", 51 | "redbox-react": "^1.4.3", 52 | "roadhog": "^2.1.0" 53 | }, 54 | "lint-staged": { 55 | "**/*.{js,jsx}": "lint-staged:js", 56 | "**/*.less": "stylelint --syntax less" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /cli/base-antd-pro/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dva Demo 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/cli/base-antd-pro/src/assets/logo.jpg -------------------------------------------------------------------------------- /cli/base-antd-pro/src/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/cli/base-antd-pro/src/assets/yay.jpg -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/Authorized.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import CheckPermissions from './CheckPermissions'; 3 | 4 | class Authorized extends React.Component { 5 | render() { 6 | const { children, authority, noMatch = null } = this.props; 7 | const childrenRender = typeof children === 'undefined' ? null : children; 8 | return CheckPermissions(authority, childrenRender, noMatch); 9 | } 10 | } 11 | 12 | export default Authorized; 13 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/AuthorizedRoute.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Route, Redirect } from 'react-router-dom'; 3 | import Authorized from './Authorized'; 4 | 5 | class AuthorizedRoute extends React.Component { 6 | render() { 7 | const { 8 | component: Component, 9 | render, 10 | authority, 11 | redirectPath, 12 | ...rest 13 | } = this.props; 14 | return ( 15 | } 21 | /> 22 | } 23 | > 24 | 27 | (Component ? : render(props)) 28 | } 29 | /> 30 | 31 | ); 32 | } 33 | } 34 | 35 | export default AuthorizedRoute; 36 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/CheckPermissions.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PromiseRender from './PromiseRender'; 3 | import { CURRENT } from './index'; 4 | 5 | function isPromise(obj) { 6 | return ( 7 | !!obj && 8 | (typeof obj === 'object' || typeof obj === 'function') && 9 | typeof obj.then === 'function' 10 | ); 11 | } 12 | 13 | /** 14 | * 通用权限检查方法 15 | * Common check permissions method 16 | * @param { 权限判定 Permission judgment type string |array | Promise | Function } authority 17 | * @param { 你的权限 Your permission description type:string} currentAuthority 18 | * @param { 通过的组件 Passing components } target 19 | * @param { 未通过的组件 no pass components } Exception 20 | */ 21 | const checkPermissions = (authority, currentAuthority, target, Exception) => { 22 | // 没有判定权限.默认查看所有 23 | // Retirement authority, return target; 24 | if (!authority) { 25 | return target; 26 | } 27 | // 数组处理 28 | if (Array.isArray(authority)) { 29 | if (authority.indexOf(currentAuthority) >= 0) { 30 | return target; 31 | } 32 | return Exception; 33 | } 34 | 35 | // string 处理 36 | if (typeof authority === 'string') { 37 | if (authority === currentAuthority) { 38 | return target; 39 | } 40 | return Exception; 41 | } 42 | 43 | // Promise 处理 44 | if (isPromise(authority)) { 45 | return ; 46 | } 47 | 48 | // Function 处理 49 | if (typeof authority === 'function') { 50 | try { 51 | const bool = authority(currentAuthority); 52 | if (bool) { 53 | return target; 54 | } 55 | return Exception; 56 | } catch (error) { 57 | throw error; 58 | } 59 | } 60 | throw new Error('unsupported parameters'); 61 | }; 62 | 63 | export { checkPermissions }; 64 | 65 | const check = (authority, target, Exception) => { 66 | return checkPermissions(authority, CURRENT, target, Exception); 67 | }; 68 | 69 | export default check; 70 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/CheckPermissions.test.js: -------------------------------------------------------------------------------- 1 | import { checkPermissions } from './CheckPermissions.js'; 2 | 3 | const target = 'ok'; 4 | const error = 'error'; 5 | 6 | describe('test CheckPermissions', () => { 7 | it('Correct string permission authentication', () => { 8 | expect(checkPermissions('user', 'user', target, error)).toEqual('ok'); 9 | }); 10 | it('Correct string permission authentication', () => { 11 | expect(checkPermissions('user', 'NULL', target, error)).toEqual('error'); 12 | }); 13 | it('authority is undefined , return ok', () => { 14 | expect(checkPermissions(null, 'NULL', target, error)).toEqual('ok'); 15 | }); 16 | it('currentAuthority is undefined , return error', () => { 17 | expect(checkPermissions('admin', null, target, error)).toEqual('error'); 18 | }); 19 | it('Wrong string permission authentication', () => { 20 | expect(checkPermissions('admin', 'user', target, error)).toEqual('error'); 21 | }); 22 | it('Correct Array permission authentication', () => { 23 | expect(checkPermissions(['user', 'admin'], 'user', target, error)).toEqual( 24 | 'ok' 25 | ); 26 | }); 27 | it('Wrong Array permission authentication,currentAuthority error', () => { 28 | expect( 29 | checkPermissions(['user', 'admin'], 'user,admin', target, error) 30 | ).toEqual('error'); 31 | }); 32 | it('Wrong Array permission authentication', () => { 33 | expect(checkPermissions(['user', 'admin'], 'guest', target, error)).toEqual( 34 | 'error' 35 | ); 36 | }); 37 | it('Wrong Function permission authentication', () => { 38 | expect(checkPermissions(() => false, 'guest', target, error)).toEqual( 39 | 'error' 40 | ); 41 | }); 42 | it('Correct Function permission authentication', () => { 43 | expect(checkPermissions(() => true, 'guest', target, error)).toEqual('ok'); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/PromiseRender.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Spin } from 'antd'; 3 | 4 | export default class PromiseRender extends React.PureComponent { 5 | state = { 6 | component: null, 7 | }; 8 | componentDidMount() { 9 | const ok = this.checkIsInstantiation(this.props.ok); 10 | const error = this.checkIsInstantiation(this.props.error); 11 | this.props.promise 12 | .then(() => { 13 | this.setState({ 14 | component: ok, 15 | }); 16 | }) 17 | .catch(() => { 18 | this.setState({ 19 | component: error, 20 | }); 21 | }); 22 | } 23 | // Determine whether the incoming component has been instantiated 24 | // AuthorizedRoute is already instantiated 25 | // Authorized render is already instantiated, children is no instantiated 26 | // Secured is not instantiated 27 | checkIsInstantiation = (target) => { 28 | if (!React.isValidElement(target)) { 29 | return target; 30 | } 31 | return () => target; 32 | }; 33 | render() { 34 | const Component = this.state.component; 35 | return Component ? ( 36 | 37 | ) : ( 38 |
47 | 48 |
49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/Secured.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Exception from '../Exception/index'; 3 | import CheckPermissions from './CheckPermissions'; 4 | /** 5 | * 默认不能访问任何页面 6 | * default is "NULL" 7 | */ 8 | const Exception403 = () => ( 9 | 10 | ); 11 | 12 | /** 13 | * 用于判断是否拥有权限访问此view权限 14 | * authority 支持传入 string ,funtion:()=>boolean|Promise 15 | * e.g. 'user' 只有user用户能访问 16 | * e.g. 'user,admin' user和 admin 都能访问 17 | * e.g. ()=>boolean 返回true能访问,返回false不能访问 18 | * e.g. Promise then 能访问 catch不能访问 19 | * e.g. authority support incoming string, funtion: () => boolean | Promise 20 | * e.g. 'user' only user user can access 21 | * e.g. 'user, admin' user and admin can access 22 | * e.g. () => boolean true to be able to visit, return false can not be accessed 23 | * e.g. Promise then can not access the visit to catch 24 | * @param {string | function | Promise} authority 25 | * @param {ReactNode} error 非必需参数 26 | */ 27 | const authorize = (authority, error) => { 28 | /** 29 | * conversion into a class 30 | * 防止传入字符串时找不到staticContext造成报错 31 | * String parameters can cause staticContext not found error 32 | */ 33 | let classError = false; 34 | if (error) { 35 | classError = () => error; 36 | } 37 | if (!authority) { 38 | throw new Error('authority is required'); 39 | } 40 | return function decideAuthority(targer) { 41 | return () => CheckPermissions(authority, targer, classError || Exception403); 42 | }; 43 | }; 44 | 45 | export default authorize; 46 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Authorized/index.js: -------------------------------------------------------------------------------- 1 | import Authorized from './Authorized'; 2 | import AuthorizedRoute from './AuthorizedRoute'; 3 | import Secured from './Secured'; 4 | import check from './CheckPermissions.js'; 5 | 6 | /* eslint-disable import/no-mutable-exports */ 7 | let CURRENT = 'NULL'; 8 | 9 | Authorized.Secured = Secured; 10 | Authorized.AuthorizedRoute = AuthorizedRoute; 11 | Authorized.check = check; 12 | 13 | /** 14 | * use authority or getAuthority 15 | * @param {string|()=>String} currentAuthority 16 | */ 17 | const renderAuthorize = (currentAuthority) => { 18 | if (currentAuthority) { 19 | if (currentAuthority.constructor.name === 'Function') { 20 | CURRENT = currentAuthority(); 21 | } 22 | if (currentAuthority.constructor.name === 'String') { 23 | CURRENT = currentAuthority; 24 | } 25 | } else { 26 | CURRENT = 'NULL'; 27 | } 28 | return Authorized; 29 | }; 30 | 31 | export { CURRENT }; 32 | export default renderAuthorize; 33 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Exception/index.js: -------------------------------------------------------------------------------- 1 | import React, { createElement } from 'react'; 2 | import classNames from 'classnames'; 3 | import { Button } from 'antd'; 4 | import config from './typeConfig'; 5 | import styles from './index.less'; 6 | 7 | export default ({ className, linkElement = 'a', type, title, desc, img, actions, ...rest }) => { 8 | const pageType = type in config ? type : '404'; 9 | const clsString = classNames(styles.exception, className); 10 | return ( 11 |
12 |
13 |
17 |
18 |
19 |

{title || config[pageType].title}

20 |
{desc || config[pageType].desc}
21 |
22 | { 23 | actions || 24 | createElement(linkElement, { 25 | to: '/', 26 | href: '/', 27 | }, ) 28 | } 29 |
30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Exception/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .exception { 4 | display: flex; 5 | align-items: center; 6 | height: 100%; 7 | 8 | .imgBlock { 9 | flex: 0 0 62.5%; 10 | width: 62.5%; 11 | padding-right: 152px; 12 | zoom: 1; 13 | &:before, 14 | &:after { 15 | content: " "; 16 | display: table; 17 | } 18 | &:after { 19 | clear: both; 20 | visibility: hidden; 21 | font-size: 0; 22 | height: 0; 23 | } 24 | } 25 | 26 | .imgEle { 27 | height: 360px; 28 | width: 100%; 29 | max-width: 430px; 30 | float: right; 31 | background-repeat: no-repeat; 32 | background-position: 50% 50%; 33 | background-size: contain; 34 | } 35 | 36 | .content { 37 | flex: auto; 38 | 39 | h1 { 40 | color: #434e59; 41 | font-size: 72px; 42 | font-weight: 600; 43 | line-height: 72px; 44 | margin-bottom: 24px; 45 | } 46 | 47 | .desc { 48 | color: @text-color-secondary; 49 | font-size: 20px; 50 | line-height: 28px; 51 | margin-bottom: 16px; 52 | } 53 | 54 | .actions { 55 | button:not(:last-child) { 56 | margin-right: 8px; 57 | } 58 | } 59 | } 60 | } 61 | 62 | @media screen and (max-width: @screen-xl) { 63 | .exception { 64 | .imgBlock { 65 | padding-right: 88px; 66 | } 67 | } 68 | } 69 | 70 | @media screen and (max-width: @screen-sm) { 71 | .exception { 72 | display: block; 73 | text-align: center; 74 | .imgBlock { 75 | padding-right: 0; 76 | margin: 0 auto 24px; 77 | } 78 | } 79 | } 80 | 81 | @media screen and (max-width: @screen-xs) { 82 | .exception { 83 | .imgBlock { 84 | margin-bottom: -24px; 85 | overflow: hidden; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Exception/typeConfig.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | 403: { 3 | img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg', 4 | title: '403', 5 | desc: '抱歉,你无权访问该页面', 6 | }, 7 | 404: { 8 | img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg', 9 | title: '404', 10 | desc: '抱歉,你访问的页面不存在', 11 | }, 12 | 500: { 13 | img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg', 14 | title: '500', 15 | desc: '抱歉,服务器出错了', 16 | }, 17 | }; 18 | 19 | export default config; 20 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/GlobalFooter/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | import styles from './index.less'; 4 | 5 | export default ({ className, links, copyright }) => { 6 | const clsString = classNames(styles.globalFooter, className); 7 | return ( 8 |
9 | { 10 | links && ( 11 |
12 | {links.map(link => ( 13 | 18 | {link.title} 19 | 20 | ))} 21 |
22 | ) 23 | } 24 | {copyright &&
{copyright}
} 25 |
26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/GlobalFooter/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .globalFooter { 4 | padding: 0 16px; 5 | margin: 48px 0 24px 0; 6 | text-align: center; 7 | 8 | .links { 9 | margin-bottom: 8px; 10 | 11 | a { 12 | color: @text-color-secondary; 13 | transition: all .3s; 14 | 15 | &:not(:last-child) { 16 | margin-right: 40px; 17 | } 18 | 19 | &:hover { 20 | color: @text-color; 21 | } 22 | } 23 | } 24 | 25 | .copyright { 26 | color: @text-color-secondary; 27 | font-size: @font-size-base; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/HeaderSearch/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .headerSearch { 4 | :global(.anticon-search) { 5 | cursor: pointer; 6 | font-size: 16px; 7 | } 8 | .input { 9 | transition: width .3s, margin-left .3s; 10 | width: 0; 11 | background: transparent; 12 | border-radius: 0; 13 | :global(.ant-select-selection) { 14 | background: transparent; 15 | } 16 | input { 17 | border: 0; 18 | padding-left: 0; 19 | padding-right: 0; 20 | box-shadow: none !important; 21 | } 22 | &, 23 | &:hover, 24 | &:focus { 25 | border-bottom: 1px solid @border-color-base; 26 | } 27 | &.show { 28 | width: 210px; 29 | margin-left: 8px; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/components/Login/LoginSubmit.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | import { Button, Form } from 'antd'; 4 | import styles from './index.less'; 5 | 6 | const FormItem = Form.Item; 7 | 8 | export default ({ className, ...rest }) => { 9 | const clsString = classNames(styles.submit, className); 10 | return ( 11 | 12 | 52 | 55 | 58 | 61 | 62 | 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/routes/Result/Error.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button, Icon, Card } from 'antd'; 3 | import Result from '../../components/Result'; 4 | import PageHeaderLayout from '../../layouts/PageHeaderLayout'; 5 | 6 | const extra = ( 7 |
8 |
9 | 您提交的内容有如下错误: 10 |
11 |
12 | 您的账户已被冻结 13 | 立即解冻 14 |
15 |
16 | 您的账户还不具备申请资格 17 | 立即升级 18 |
19 |
20 | ); 21 | 22 | const actions = ; 23 | 24 | export default () => ( 25 | 26 | 27 | 35 | 36 | 37 | ); 38 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/routes/Result/Success.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow } from 'enzyme'; 3 | import Success from './Success'; 4 | 5 | it('renders with Result', () => { 6 | const wrapper = shallow(); 7 | expect(wrapper.find('Result').length).toBe(1); 8 | expect(wrapper.find('Result').prop('type')).toBe('success'); 9 | }); 10 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/routes/User/Login.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .main { 4 | width: 368px; 5 | margin: 0 auto; 6 | 7 | .icon { 8 | font-size: 24px; 9 | color: rgba(0, 0, 0, 0.2); 10 | margin-left: 16px; 11 | vertical-align: middle; 12 | cursor: pointer; 13 | transition: color .3s; 14 | 15 | &:hover { 16 | color: @primary-color; 17 | } 18 | } 19 | 20 | .other { 21 | text-align: left; 22 | margin-top: 24px; 23 | line-height: 22px; 24 | 25 | .register { 26 | float: right; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/routes/User/Register.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .main { 4 | width: 368px; 5 | margin: 0 auto; 6 | 7 | :global { 8 | .ant-form-item { 9 | margin-bottom: 24px; 10 | } 11 | } 12 | 13 | h3 { 14 | font-size: 16px; 15 | margin-bottom: 20px; 16 | } 17 | 18 | .getCaptcha { 19 | display: block; 20 | width: 100%; 21 | } 22 | 23 | .submit { 24 | width: 50%; 25 | } 26 | 27 | .login { 28 | float: right; 29 | line-height: @btn-height-lg; 30 | } 31 | } 32 | 33 | .success, 34 | .warning, 35 | .error { 36 | transition: color 0.3s; 37 | } 38 | 39 | .success { 40 | color: @success-color; 41 | } 42 | 43 | .warning { 44 | color: @warning-color; 45 | } 46 | 47 | .error { 48 | color: @error-color; 49 | } 50 | 51 | .progress-pass > .progress { 52 | :global { 53 | .ant-progress-bg { 54 | background-color: @warning-color; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/routes/User/RegisterResult.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button } from 'antd'; 3 | import { Link } from 'dva/router'; 4 | import Result from '../../components/Result'; 5 | import styles from './RegisterResult.less'; 6 | 7 | const actions = ( 8 |
9 | 10 | 11 |
12 | ); 13 | 14 | export default ({ location }) => ( 15 | 20 | 你的账户:{location.state ? location.state.account : 'AntDesign@example.com'} 注册成功 21 |
22 | } 23 | description="激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。" 24 | actions={actions} 25 | style={{ marginTop: 56 }} 26 | /> 27 | ); 28 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/routes/User/RegisterResult.less: -------------------------------------------------------------------------------- 1 | .registerResult { 2 | :global { 3 | .anticon { 4 | font-size: 64px; 5 | } 6 | } 7 | .title { 8 | margin-top: 32px; 9 | font-size: 20px; 10 | line-height: 28px; 11 | } 12 | .actions { 13 | margin-top: 40px; 14 | a + a { 15 | margin-left: 8px; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/services/api.js: -------------------------------------------------------------------------------- 1 | import { stringify } from 'qs'; 2 | import request from '../utils/request'; 3 | 4 | export async function queryProjectNotice() { 5 | return request('/api/project/notice'); 6 | } 7 | 8 | export async function queryActivities() { 9 | return request('/api/activities'); 10 | } 11 | 12 | export async function queryRule(params) { 13 | return request(`/api/rule?${stringify(params)}`); 14 | } 15 | 16 | export async function removeRule(params) { 17 | return request('/api/rule', { 18 | method: 'POST', 19 | body: { 20 | ...params, 21 | method: 'delete', 22 | }, 23 | }); 24 | } 25 | 26 | export async function addRule(params) { 27 | return request('/api/rule', { 28 | method: 'POST', 29 | body: { 30 | ...params, 31 | method: 'post', 32 | }, 33 | }); 34 | } 35 | 36 | export async function fakeSubmitForm(params) { 37 | return request('/api/forms', { 38 | method: 'POST', 39 | body: params, 40 | }); 41 | } 42 | 43 | export async function fakeChartData() { 44 | return request('/api/fake_chart_data'); 45 | } 46 | 47 | export async function queryTags() { 48 | return request('/api/tags'); 49 | } 50 | 51 | export async function queryBasicProfile() { 52 | return request('/api/profile/basic'); 53 | } 54 | 55 | export async function queryAdvancedProfile() { 56 | return request('/api/profile/advanced'); 57 | } 58 | 59 | export async function queryFakeList(params) { 60 | return request(`/api/fake_list?${stringify(params)}`); 61 | } 62 | 63 | export async function fakeAccountLogin(params) { 64 | return request('/api/login/account', { 65 | method: 'POST', 66 | body: params, 67 | }); 68 | } 69 | 70 | export async function fakeRegister(params) { 71 | return request('/api/register', { 72 | method: 'POST', 73 | body: params, 74 | }); 75 | } 76 | 77 | export async function queryNotices() { 78 | return request('/api/notices'); 79 | } 80 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/services/error.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export async function query404() { 4 | return request('/api/404'); 5 | } 6 | 7 | export async function query401() { 8 | return request('/api/401'); 9 | } 10 | 11 | export async function query403() { 12 | return request('/api/403'); 13 | } 14 | 15 | export async function query500() { 16 | return request('/api/500'); 17 | } 18 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/services/user.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export async function query() { 4 | return request('/api/users'); 5 | } 6 | 7 | export async function queryCurrent() { 8 | return request('/api/currentUser'); 9 | } 10 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/theme.js: -------------------------------------------------------------------------------- 1 | // https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less 2 | module.exports = { 3 | // 'primary-color': '#10e99b', 4 | //'card-actions-background': '#f5f8fa', 5 | }; 6 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/utils/Authorized.js: -------------------------------------------------------------------------------- 1 | import RenderAuthorized from '../components/Authorized'; 2 | import { getAuthority } from './authority'; 3 | 4 | let Authorized = RenderAuthorized(getAuthority()); // eslint-disable-line 5 | 6 | // Reload the rights component 7 | const reloadAuthorized = () => { 8 | Authorized = RenderAuthorized(getAuthority()); 9 | }; 10 | 11 | export { reloadAuthorized }; 12 | export default Authorized; 13 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/utils/authority.js: -------------------------------------------------------------------------------- 1 | // use localStorage to store the authority info, which might be sent from server in actual project. 2 | export function getAuthority() { 3 | return localStorage.getItem('antd-pro-authority') || 'admin'; 4 | } 5 | 6 | export function setAuthority(authority) { 7 | return localStorage.setItem('antd-pro-authority', authority); 8 | } 9 | -------------------------------------------------------------------------------- /cli/base-antd-pro/src/utils/utils.less: -------------------------------------------------------------------------------- 1 | .textOverflow() { 2 | overflow: hidden; 3 | text-overflow: ellipsis; 4 | word-break: break-all; 5 | white-space: nowrap; 6 | } 7 | 8 | .textOverflowMulti(@line: 3, @bg: #fff) { 9 | overflow: hidden; 10 | position: relative; 11 | line-height: 1.5em; 12 | max-height: @line * 1.5em; 13 | text-align: justify; 14 | margin-right: -1em; 15 | padding-right: 1em; 16 | &:before { 17 | background: @bg; 18 | content: '...'; 19 | padding: 0 1px; 20 | position: absolute; 21 | right: 14px; 22 | bottom: 0; 23 | } 24 | &:after { 25 | background: white; 26 | content: ''; 27 | margin-top: 0.2em; 28 | position: absolute; 29 | right: 14px; 30 | width: 1em; 31 | height: 1em; 32 | } 33 | } 34 | 35 | // mixins for clearfix 36 | // ------------------------ 37 | .clearfix() { 38 | zoom: 1; 39 | &:before, 40 | &:after { 41 | content: " "; 42 | display: table; 43 | } 44 | &:after { 45 | clear: both; 46 | visibility: hidden; 47 | font-size: 0; 48 | height: 0; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /cli/react-antd-dva/README.md: -------------------------------------------------------------------------------- 1 | ## FXBlog ui 2 | 3 | base on react、dva、antd and so on。 4 | 5 | The basic framework is modified according to [ant design pro](https://pro.ant.design/index-cn). 6 | 7 | ## run 8 | 9 | ```shell 10 | 11 | $ cd fx-blog-show 12 | $ npm install & npm start 13 | 14 | ``` 15 | 16 | visit on bowser: http://localhost:8000/home -------------------------------------------------------------------------------- /cli/react-antd-dva/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "cross-env DISABLE_ESLINT=true roadhog dev", 5 | "build": "roadhog build", 6 | "lint": "eslint --ext .js src test", 7 | "precommit": "npm run lint" 8 | }, 9 | "dependencies": { 10 | "@babel/polyfill": "^7.0.0-beta.36", 11 | "antd": "^3.2.0", 12 | "babel-plugin-import": "^1.6.3", 13 | "classnames": "^2.2.5", 14 | "dva": "^2.1.0", 15 | "dva-loading": "^1.0.4", 16 | "enquire-js": "^0.1.1", 17 | "fastclick": "^1.0.6", 18 | "lodash": "^4.17.4", 19 | "lodash-decorators": "^4.4.1", 20 | "moment": "^2.19.1", 21 | "qs": "^6.5.0", 22 | "rc-drawer-menu": "^0.5.0", 23 | "react": "^16.2.0", 24 | "react-container-query": "^0.9.1", 25 | "react-document-title": "^2.0.3", 26 | "react-dom": "^16.2.0", 27 | "react-fittext": "^1.0.0", 28 | "url-polyfill": "^1.0.10" 29 | }, 30 | "devDependencies": { 31 | "babel-plugin-dva-hmr": "^0.3.2", 32 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 33 | "cross-env": "^5.1.1", 34 | "cross-port-killer": "^1.0.1", 35 | "eslint": "^4.14.0", 36 | "eslint-config-umi": "^0.1.1", 37 | "eslint-plugin-flowtype": "^2.34.1", 38 | "eslint-plugin-import": "^2.6.0", 39 | "eslint-plugin-jsx-a11y": "^5.1.1", 40 | "eslint-plugin-react": "^7.1.0", 41 | "husky": "^0.12.0", 42 | "redbox-react": "^1.4.3", 43 | "roadhog": "^2.1.0" 44 | }, 45 | "lint-staged": { 46 | "**/*.{js,jsx}": "lint-staged:js", 47 | "**/*.less": "stylelint --syntax less" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /cli/react-antd-dva/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dva Demo 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/cli/react-antd-dva/src/assets/logo.jpg -------------------------------------------------------------------------------- /cli/react-antd-dva/src/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/cli/react-antd-dva/src/assets/yay.jpg -------------------------------------------------------------------------------- /cli/react-antd-dva/src/common/menu.js: -------------------------------------------------------------------------------- 1 | import { isUrl } from '../utils/utils'; 2 | 3 | const menuData = [{ 4 | name: 'java', 5 | icon: 'dashboard', 6 | path: 'home1', 7 | children: [{ 8 | name: 'java1', 9 | path: 'home2', 10 | }, { 11 | name: 'java2', 12 | path: 'home3', 13 | }, { 14 | name: 'java3', 15 | path: 'home4', 16 | // hideInMenu: true, 17 | }], 18 | }, { 19 | name: 'linux', 20 | icon: 'form', 21 | path: 'form5', 22 | children: [{ 23 | name: 'linux1', 24 | path: 'home6', 25 | }, { 26 | name: 'linux2', 27 | path: 'home7', 28 | }, { 29 | name: 'linux3', 30 | path: 'home8', 31 | children: [{ 32 | name: 'linux3-1', 33 | path: 'home9', 34 | }, { 35 | name: 'linux3-2', 36 | path: 'home0', 37 | }, { 38 | name: 'linux3-3', 39 | path: 'homex', 40 | }], 41 | }], 42 | }]; 43 | 44 | function formatter(data, parentPath = '', parentAuthority) { 45 | return data.map((item) => { 46 | let { path } = item; 47 | if (!isUrl(path)) { 48 | path = parentPath + item.path; 49 | } 50 | const result = { 51 | ...item, 52 | path, 53 | authority: item.authority || parentAuthority, 54 | }; 55 | if (item.children) { 56 | result.children = formatter(item.children, `${parentPath}${item.path}/`, item.authority); 57 | } 58 | return result; 59 | }); 60 | } 61 | 62 | export const getMenuData = () => formatter(menuData); 63 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/Exception/index.js: -------------------------------------------------------------------------------- 1 | import React, { createElement } from 'react'; 2 | import classNames from 'classnames'; 3 | import { Button } from 'antd'; 4 | import config from './typeConfig'; 5 | import styles from './index.less'; 6 | 7 | export default ({ className, linkElement = 'a', type, title, desc, img, actions, ...rest }) => { 8 | const pageType = type in config ? type : '404'; 9 | const clsString = classNames(styles.exception, className); 10 | return ( 11 |
12 |
13 |
17 |
18 |
19 |

{title || config[pageType].title}

20 |
{desc || config[pageType].desc}
21 |
22 | { 23 | actions || 24 | createElement(linkElement, { 25 | to: '/', 26 | href: '/', 27 | }, ) 28 | } 29 |
30 |
31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/Exception/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .exception { 4 | display: flex; 5 | align-items: center; 6 | height: 100%; 7 | 8 | .imgBlock { 9 | flex: 0 0 62.5%; 10 | width: 62.5%; 11 | padding-right: 152px; 12 | zoom: 1; 13 | &:before, 14 | &:after { 15 | content: " "; 16 | display: table; 17 | } 18 | &:after { 19 | clear: both; 20 | visibility: hidden; 21 | font-size: 0; 22 | height: 0; 23 | } 24 | } 25 | 26 | .imgEle { 27 | height: 360px; 28 | width: 100%; 29 | max-width: 430px; 30 | float: right; 31 | background-repeat: no-repeat; 32 | background-position: 50% 50%; 33 | background-size: contain; 34 | } 35 | 36 | .content { 37 | flex: auto; 38 | 39 | h1 { 40 | color: #434e59; 41 | font-size: 72px; 42 | font-weight: 600; 43 | line-height: 72px; 44 | margin-bottom: 24px; 45 | } 46 | 47 | .desc { 48 | color: @text-color-secondary; 49 | font-size: 20px; 50 | line-height: 28px; 51 | margin-bottom: 16px; 52 | } 53 | 54 | .actions { 55 | button:not(:last-child) { 56 | margin-right: 8px; 57 | } 58 | } 59 | } 60 | } 61 | 62 | @media screen and (max-width: @screen-xl) { 63 | .exception { 64 | .imgBlock { 65 | padding-right: 88px; 66 | } 67 | } 68 | } 69 | 70 | @media screen and (max-width: @screen-sm) { 71 | .exception { 72 | display: block; 73 | text-align: center; 74 | .imgBlock { 75 | padding-right: 0; 76 | margin: 0 auto 24px; 77 | } 78 | } 79 | } 80 | 81 | @media screen and (max-width: @screen-xs) { 82 | .exception { 83 | .imgBlock { 84 | margin-bottom: -24px; 85 | overflow: hidden; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/Exception/typeConfig.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | 403: { 3 | img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg', 4 | title: '403', 5 | desc: '抱歉,你无权访问该页面', 6 | }, 7 | 404: { 8 | img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg', 9 | title: '404', 10 | desc: '抱歉,你访问的页面不存在', 11 | }, 12 | 500: { 13 | img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg', 14 | title: '500', 15 | desc: '抱歉,服务器出错了', 16 | }, 17 | }; 18 | 19 | export default config; 20 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/GlobalFooter/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import classNames from 'classnames'; 3 | import styles from './index.less'; 4 | 5 | export default ({ className, links, copyright }) => { 6 | const clsString = classNames(styles.globalFooter, className); 7 | return ( 8 |
9 | { 10 | links && ( 11 |
12 | {links.map(link => ( 13 | 18 | {link.title} 19 | 20 | ))} 21 |
22 | ) 23 | } 24 | {copyright &&
{copyright}
} 25 |
26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/GlobalFooter/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .globalFooter { 4 | padding: 0 16px; 5 | margin: 48px 0 24px 0; 6 | text-align: center; 7 | 8 | .links { 9 | margin-bottom: 8px; 10 | 11 | a { 12 | color: @text-color-secondary; 13 | transition: all .3s; 14 | 15 | &:not(:last-child) { 16 | margin-right: 40px; 17 | } 18 | 19 | &:hover { 20 | color: @text-color; 21 | } 22 | } 23 | } 24 | 25 | .copyright { 26 | color: @text-color-secondary; 27 | font-size: @font-size-base; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/GlobalHeader/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { Layout, Divider } from 'antd'; 3 | 4 | import { Link } from 'dva/router'; 5 | 6 | import HeaderSearch from '../HeaderSearch'; 7 | import HeaderMenu from '../HeaderMenu'; 8 | import HeaderLogo from '../HeaderLogo'; 9 | import styles from './index.less'; 10 | import { getMenuData } from '../../common/menu'; 11 | 12 | const { Header } = Layout; 13 | 14 | 15 | export default class GlobalHeader extends PureComponent { 16 | componentWillUnmount() { 17 | this.triggerResizeEvent.cancel(); 18 | } 19 | 20 | render() { 21 | const { 22 | isMobile, logo, location 23 | } = this.props; 24 | 25 | return ( 26 |
27 | {isMobile && ( 28 | [ 29 | ( 30 | 31 | logo 32 | 33 | ), 34 | , 35 | ] 36 | )} 37 | 41 | 47 |
48 | { 53 | console.log('input', value); // eslint-disable-line 54 | }} 55 | onPressEnter={(value) => { 56 | console.log('enter', value); // eslint-disable-line 57 | }} 58 | /> 59 | 60 |
61 |
62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/HeaderLogo/index.js: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react'; 2 | import { Link } from 'dva/router'; 3 | import styles from './index.less'; 4 | 5 | 6 | export default class HeaderLogo extends PureComponent { 7 | 8 | render() { 9 | const { logo } = this.props; 10 | return ( 11 |
12 | 13 | logo 14 |

Blog

15 | 16 |
17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/HeaderLogo/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | @ease-in-out-circ: cubic-bezier(.78, .14, .15, .86); 3 | .logo { 4 | height: 64px; 5 | position: relative; 6 | line-height: 64px; 7 | max-height: 64px; 8 | padding-left: (@menu-collapsed-width - 32px) / 2; 9 | padding-right: (@menu-collapsed-width - 32px) / 2; 10 | transition: all .3s; 11 | // background: #002140; 12 | overflow: hidden; 13 | display: inline-block; 14 | img { 15 | width: 48px; 16 | height: 48px; 17 | vertical-align: middle; 18 | } 19 | h1 { 20 | color: rgb(7, 2, 24); 21 | display: inline; 22 | vertical-align: middle; 23 | font-size: 20px; 24 | margin: 0 0 0 12px; 25 | font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif; 26 | font-weight: 600; 27 | } 28 | } -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/HeaderMenu/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | @ease-in-out-circ: cubic-bezier(.78, .14, .15, .86); 3 | 4 | 5 | // .sider { 6 | // min-height: 100vh; 7 | // // box-shadow: 2px 0 6px rgba(0, 21, 41, .35); 8 | // position: relative; 9 | // z-index: 10; 10 | // } 11 | 12 | // .icon { 13 | // width: 14px; 14 | // margin-right: 10px; 15 | // } 16 | 17 | // :global { 18 | // .drawer .drawer-content { 19 | // // background: #001529; 20 | // } 21 | // } 22 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/components/HeaderSearch/index.less: -------------------------------------------------------------------------------- 1 | @import "~antd/lib/style/themes/default.less"; 2 | 3 | .headerSearch { 4 | :global(.anticon-search) { 5 | cursor: pointer; 6 | font-size: 16px; 7 | } 8 | .input { 9 | transition: width .3s, margin-left .3s; 10 | width: 0; 11 | background: transparent; 12 | border-radius: 0; 13 | :global(.ant-select-selection) { 14 | background: transparent; 15 | } 16 | input { 17 | border: 0; 18 | padding-left: 0; 19 | padding-right: 0; 20 | box-shadow: none !important; 21 | } 22 | &, 23 | &:hover, 24 | &:focus { 25 | border-bottom: 1px solid @border-color-base; 26 | } 27 | &.show { 28 | width: 210px; 29 | margin-left: 8px; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Ant Design Pro 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/index.js: -------------------------------------------------------------------------------- 1 | import '@babel/polyfill'; 2 | import 'url-polyfill'; 3 | import dva from 'dva'; 4 | 5 | import createHistory from 'history/createHashHistory'; 6 | // user BrowserHistory 7 | // import createHistory from 'history/createBrowserHistory'; 8 | import createLoading from 'dva-loading'; 9 | // import 'moment/locale/zh-cn'; 10 | import FastClick from 'fastclick'; 11 | // import './rollbar'; 12 | 13 | import './index.less'; 14 | // 1. Initialize 15 | const app = dva({ 16 | history: createHistory(), 17 | }); 18 | 19 | // 2. Plugins 20 | app.use(createLoading()); 21 | 22 | // 3. Register global model 23 | app.model(require('./models/global').default); 24 | 25 | // 4. Router 26 | app.router(require('./router').default); 27 | 28 | // 5. Start 29 | app.start('#root'); 30 | 31 | 32 | FastClick.attach(document.body); 33 | 34 | export default app._store; // eslint-disable-line 35 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/index.less: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | :global(#root) { 4 | height: 100%; 5 | } 6 | 7 | :global(.ant-layout) { 8 | min-height: 100%; 9 | } 10 | 11 | canvas { 12 | display: block; 13 | } 14 | 15 | body { 16 | text-rendering: optimizeLegibility; 17 | -webkit-font-smoothing: antialiased; 18 | -moz-osx-font-smoothing: grayscale; 19 | } 20 | 21 | .globalSpin { 22 | width: 100%; 23 | margin: 40px 0 !important; 24 | } 25 | 26 | // temp fix for https://github.com/ant-design/ant-design/commit/a1fafb5b727b62cb0be29ce6e9eca8f579d4f8b7 27 | :global { 28 | .ant-spin-container { 29 | overflow: visible !important; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/models/global.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespace: 'global', 3 | 4 | state: { 5 | notices: [], 6 | }, 7 | } -------------------------------------------------------------------------------- /cli/react-antd-dva/src/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { routerRedux, Route, Switch } from 'dva/router'; 3 | import { Spin } from 'antd'; 4 | 5 | import dynamic from 'dva/dynamic'; 6 | import { getRouterData } from './common/router'; 7 | 8 | import styles from './index.less'; 9 | 10 | const { ConnectedRouter } = routerRedux; 11 | 12 | dynamic.setDefaultLoadingComponent(() => { 13 | return ; 14 | }); 15 | 16 | function RouterConfig({ history, app }) { 17 | const routerData = getRouterData(app); 18 | const BasicLayout = routerData['/'].component; 19 | return ( 20 | 21 | 22 | } 25 | /> 26 | 27 | 28 | ); 29 | } 30 | 31 | export default RouterConfig; 32 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/routes/ArticleList/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const ArticleList = (props) => ( 4 |

List of Article

5 | ); 6 | 7 | export default ArticleList; -------------------------------------------------------------------------------- /cli/react-antd-dva/src/routes/ArticleList/index.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/cli/react-antd-dva/src/routes/ArticleList/index.less -------------------------------------------------------------------------------- /cli/react-antd-dva/src/routes/Exception/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'dva/router'; 3 | import Exception from '../../components/Exception'; 4 | 5 | export default () => ( 6 | 7 | ); 8 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/services/example.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export function query() { 4 | return request('/api/users'); 5 | } 6 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/theme.js: -------------------------------------------------------------------------------- 1 | // https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less 2 | module.exports = { 3 | // 'primary-color': '#10e99b', 4 | //'card-actions-background': '#f5f8fa', 5 | }; 6 | -------------------------------------------------------------------------------- /cli/react-antd-dva/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import fetch from 'dva/fetch'; 2 | 3 | function parseJSON(response) { 4 | return response.json(); 5 | } 6 | 7 | function checkStatus(response) { 8 | if (response.status >= 200 && response.status < 300) { 9 | return response; 10 | } 11 | 12 | const error = new Error(response.statusText); 13 | error.response = response; 14 | throw error; 15 | } 16 | 17 | /** 18 | * Requests a URL, returning a promise. 19 | * 20 | * @param {string} url The URL we want to request 21 | * @param {object} [options] The options we want to pass to "fetch" 22 | * @return {object} An object containing either "data" or "err" 23 | */ 24 | export default function request(url, options) { 25 | return fetch(url, options) 26 | .then(checkStatus) 27 | .then(parseJSON) 28 | .then(data => ({ data })) 29 | .catch(err => ({ err })); 30 | } 31 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "rules": { 5 | "generator-star-spacing": [0], 6 | "consistent-return": [0], 7 | "react/forbid-prop-types": [0], 8 | "react/jsx-filename-extension": [1, { "extensions": [".js"] }], 9 | "global-require": [1], 10 | "import/prefer-default-export": [0], 11 | "react/jsx-no-bind": [0], 12 | "react/prop-types": [0], 13 | "react/prefer-stateless-function": [0], 14 | "no-else-return": [0], 15 | "no-restricted-syntax": [0], 16 | "import/no-extraneous-dependencies": [0], 17 | "no-use-before-define": [0], 18 | "jsx-a11y/no-static-element-interactions": [0], 19 | "no-nested-ternary": [0], 20 | "arrow-body-style": [0], 21 | "import/extensions": [0], 22 | "no-bitwise": [0], 23 | "no-cond-assign": [0], 24 | "import/no-unresolved": [0], 25 | "require-yield": [1] 26 | }, 27 | "parserOptions": { 28 | "ecmaFeatures": { 29 | "experimentalObjectRestSpread": true 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # production 7 | /dist 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log* 12 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/.roadhogrc: -------------------------------------------------------------------------------- 1 | { 2 | "entry": "src/index.js", 3 | "env": { 4 | "development": { 5 | "extraBabelPlugins": [ 6 | "dva-hmr", 7 | "transform-runtime", 8 | ["import", { "libraryName": "antd", "style": true }] 9 | ] 10 | }, 11 | "production": { 12 | "extraBabelPlugins": [ 13 | "transform-runtime", 14 | ["import", { "libraryName": "antd", "style": true }] 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/.roadhogrc.mock.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | }; 4 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "roadhog server", 5 | "build": "roadhog build" 6 | }, 7 | "engines": { 8 | "install-node": "6.9.2" 9 | }, 10 | "dependencies": { 11 | "antd": "^2.10.2", 12 | "babel-plugin-import": "^1.2.0", 13 | "babel-runtime": "^6.9.2", 14 | "classnames": "^2.2.5", 15 | "dva": "^1.2.1", 16 | "react": "^15.4.0", 17 | "react-dom": "^15.4.0" 18 | }, 19 | "devDependencies": { 20 | "babel-eslint": "^7.1.1", 21 | "babel-plugin-dva-hmr": "^0.3.2", 22 | "babel-plugin-transform-runtime": "^6.9.0", 23 | "eslint": "^3.12.2", 24 | "eslint-config-airbnb": "^13.0.0", 25 | "eslint-plugin-import": "^2.2.0", 26 | "eslint-plugin-jsx-a11y": "^2.2.3", 27 | "eslint-plugin-react": "^6.8.0", 28 | "expect": "^1.20.2", 29 | "husky": "^0.12.0", 30 | "redbox-react": "^1.3.2", 31 | "roadhog": "^0.5.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dva Demo 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/higher-demo/dva-antd/antd-ui/src/assets/yay.jpg -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/components/EditableTable.less: -------------------------------------------------------------------------------- 1 | ///*@import 'antd/dist/antd.css';*/ 2 | // 3 | //.editableTable { 4 | // :global(.ant-table-thead tr) { 5 | // th { 6 | // padding: 11px 8px 11px 11px; 7 | // } 8 | // 9 | // th:first-child { 10 | // padding-left: 15px; 11 | // } 12 | // 13 | // th:last-child { 14 | // padding-left: 35px; 15 | // } 16 | // } 17 | // 18 | // :global(.ant-table-tbody) { 19 | // td { 20 | // padding: 9px 8px; 21 | // } 22 | // 23 | // tr:last-child td { 24 | // padding-left: 8px; 25 | // } 26 | // } 27 | // 28 | // .rowSaved { 29 | // td:not(:last-child) { 30 | // padding-left: 11px; 31 | // } 32 | // 33 | // td:first-child { 34 | // padding-left: 15px; 35 | // } 36 | // 37 | // td:last-child { 38 | // padding-left: 28px; 39 | // } 40 | // } 41 | // 42 | // .rowEditing { 43 | // color: red; 44 | // 45 | // td:not(:last-child) { 46 | // padding-left: 4px; 47 | // padding-right: 4px; 48 | // } 49 | // 50 | // td:first-child { 51 | // padding-left: 8px; 52 | // } 53 | // 54 | // td:last-child { 55 | // padding-left: 28px; 56 | // } 57 | // } 58 | // 59 | // .titleNote { 60 | // color: #8C8D8F; 61 | // } 62 | // 63 | // .addBtn { 64 | // width: 100%; 65 | // color: rgba(0, 0, 0, 0.43); 66 | // } 67 | // 68 | // .operation { 69 | // a:not(:last-child) { 70 | // padding-left: 8px; 71 | // margin-right: 24px; 72 | // } 73 | // 74 | // button { 75 | // margin-right: 16px; 76 | // } 77 | // 78 | // &.editing { 79 | // margin-right: 16px; 80 | // } 81 | // } 82 | //} 83 | // 84 | //.errorTip { 85 | // :global(.ant-tooltip-arrow) { 86 | // border-bottom-color: #f04134; 87 | // } 88 | // :global(.ant-tooltip-inner) { 89 | // background-color: #f04134; 90 | // } 91 | //} 92 | // 93 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/index.css: -------------------------------------------------------------------------------- 1 | 2 | html, body, :global(#root) { 3 | height: 100%; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/index.js: -------------------------------------------------------------------------------- 1 | import dva from 'dva'; 2 | import './index.css'; 3 | 4 | // 1. Initialize 5 | const app = dva(); 6 | 7 | // 2. Plugins 8 | // app.use({}); 9 | 10 | // 3. Model 11 | // app.model(require('./models/example')); 12 | 13 | // 4. Router 14 | app.router(require('./router')); 15 | 16 | // 5. Start 17 | app.start('#root'); 18 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route } from 'dva/router'; 3 | import IndexPage from './routes/IndexPage'; 4 | 5 | function RouterConfig({ history }) { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | export default RouterConfig; 14 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/routes/IndexPage.css: -------------------------------------------------------------------------------- 1 | 2 | .normal { 3 | font-family: Georgia, sans-serif; 4 | margin-top: 3em; 5 | text-align: center; 6 | } 7 | 8 | .title { 9 | font-size: 2.5rem; 10 | font-weight: normal; 11 | letter-spacing: -1px; 12 | } 13 | 14 | .welcome { 15 | height: 328px; 16 | background: url(../assets/yay.jpg) no-repeat center 0; 17 | background-size: 388px 328px; 18 | } 19 | 20 | .list { 21 | font-size: 1.2em; 22 | margin-top: 1.8em; 23 | list-style: none; 24 | line-height: 1.5em; 25 | } 26 | 27 | .list code { 28 | background: #f7f7f7; 29 | } 30 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/services/example.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export async function query() { 4 | return request('/api/users'); 5 | } 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/antd-ui/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import fetch from 'dva/fetch'; 2 | 3 | function parseJSON(response) { 4 | return response.json(); 5 | } 6 | 7 | function checkStatus(response) { 8 | if (response.status >= 200 && response.status < 300) { 9 | return response; 10 | } 11 | 12 | const error = new Error(response.statusText); 13 | error.response = response; 14 | throw error; 15 | } 16 | 17 | /** 18 | * Requests a URL, returning a promise. 19 | * 20 | * @param {string} url The URL we want to request 21 | * @param {object} [options] The options we want to pass to "fetch" 22 | * @return {object} An object containing either "data" or "err" 23 | */ 24 | export default function request(url, options) { 25 | return fetch(url, options) 26 | .then(checkStatus) 27 | .then(parseJSON) 28 | .then(data => ({ data })) 29 | .catch(err => ({ err })); 30 | } 31 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "rules": { 4 | "semi": [2, "never"], 5 | "no-console": 0, 6 | "comma-dangle": [2, "always-multiline"], 7 | "max-len": 0, 8 | "react/jsx-first-prop-new-line": 0, 9 | "space-before-function-paren": [2, "always"], 10 | "no-unused-expressions": [0, { 11 | "allowShortCircuit": true, 12 | "allowTernary": true 13 | }], 14 | "arrow-body-style": [0, "never"], 15 | "func-names": 0, 16 | "prefer-const": 0, 17 | "no-extend-native": 0, 18 | "no-param-reassign": 0, 19 | "no-restricted-syntax": 0, 20 | "no-eval": 0, 21 | "react/jsx-no-bind": 0, 22 | "no-unused-vars": [2, { "ignoreRestSiblings": true }], 23 | "no-underscore-dangle": 0, 24 | "global-require": 0, 25 | }, 26 | "parser": "babel-eslint", 27 | "parserOptions": { 28 | "sourceType": "module", 29 | "ecmaVersion": 8, 30 | "ecmaFeatures": { 31 | "jsx": true, 32 | "experimentalObjectRestSpread": true 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # production 7 | /dist 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log* 12 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/.roadhogrc: -------------------------------------------------------------------------------- 1 | { 2 | "entry": "src/index.js", 3 | "env": { 4 | "development": { 5 | "extraBabelPlugins": [ 6 | "dva-hmr", 7 | "transform-runtime", 8 | ["import", { "libraryName": "antd", "style": true }] 9 | ] 10 | }, 11 | "production": { 12 | "extraBabelPlugins": [ 13 | "transform-runtime", 14 | ["import", { "libraryName": "antd", "style": true }] 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/.roadhogrc.mock.js: -------------------------------------------------------------------------------- 1 | const mock = {} 2 | require('fs').readdirSync(require('path').join(__dirname + '/src/mock')).forEach(function(file) { 3 | Object.assign(mock, require('./src/mock/' + file)) 4 | }) 5 | module.exports = mock 6 | 7 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "antd": "^2.10.0", 5 | "dva": "^1.2.0", 6 | "dva-loading": "^0.2.0", 7 | "lodash": "^4.17.4", 8 | "nprogress": "^0.2.0", 9 | "qs": "^6.2.0", 10 | "react": "^15.4.4", 11 | "react-countup": "1.3.0", 12 | "react-dom": "^15.4.1", 13 | "react-draft-wysiwyg": "^1.8.1", 14 | "react-helmet": "^5.0.0" 15 | }, 16 | "devDependencies": { 17 | "axios": "^0.15.3", 18 | "babel-eslint": "^6.1.2", 19 | "babel-plugin-dev-expression": "^0.2.1", 20 | "babel-plugin-dva-hmr": "^0.3.2", 21 | "babel-plugin-import": "^1.1.1", 22 | "babel-plugin-transform-runtime": "^6.9.0", 23 | "babel-polyfill": "^6.23.0", 24 | "babel-runtime": "^6.9.2", 25 | "draftjs-to-html": "^0.7.0", 26 | "eslint": "^3.17.1", 27 | "eslint-config-airbnb": "^9.0.1", 28 | "eslint-plugin-import": "^1.16.0", 29 | "eslint-plugin-jsx-a11y": "^1.4.2", 30 | "eslint-plugin-react": "^5.1.1", 31 | "less-vars-to-js": "^1.1.2", 32 | "mockjs": "^1.0.1-beta3", 33 | "path-to-regexp": "^1.7.0", 34 | "redbox-react": "^1.2.10", 35 | "roadhog": "0.6.0-beta.6" 36 | }, 37 | "pre-commit": [ 38 | "lint" 39 | ], 40 | "scripts": { 41 | "dev": "set BROWSER=none&&set HOST=0.0.0.0&&roadhog server", 42 | "lint": "eslint --fix --ext .js src", 43 | "build": "roadhog build --analyze" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dva Demo 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/higher-demo/dva-antd/login-demo/src/assets/yay.jpg -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/components/Example.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Example = () => { 4 | return ( 5 |
6 | Example 7 |
8 | ); 9 | }; 10 | 11 | Example.propTypes = { 12 | }; 13 | 14 | export default Example; 15 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/index.css: -------------------------------------------------------------------------------- 1 | 2 | html, body, :global(#root) { 3 | height: 100%; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/index.js: -------------------------------------------------------------------------------- 1 | import dva from 'dva'; 2 | import 'babel-polyfill' 3 | import createLoading from 'dva-loading' 4 | import { browserHistory } from 'dva/router' 5 | import { message } from 'antd' 6 | import './index.css'; 7 | 8 | // 1. Initialize 9 | const app = dva({ 10 | ...createLoading({ 11 | effects: true, 12 | }), 13 | history: browserHistory, 14 | onError (error) { 15 | message.error(error.message) 16 | }, 17 | }); 18 | 19 | // 2. Plugins 20 | // app.use({}); 21 | 22 | // 3. Model 23 | app.model(require('./models/login')); 24 | 25 | // 4. Router 26 | app.router(require('./router')); 27 | 28 | // 5. Start 29 | app.start('#root'); 30 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/mock/mock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/25*/ 3 | 4 | const qs = require('qs') 5 | const Mock = require('mockjs') 6 | 7 | const userPermission = { 8 | DEFAULT: [ 9 | 'index', 10 | ], 11 | ADMIN: [ 12 | 'index', 'admin', 'users', 13 | ], 14 | USERS: [ 15 | 'index', 'users', 16 | ] 17 | }; 18 | 19 | const adminUsers = [ 20 | { 21 | id: 0, 22 | username: 'admin', 23 | password: 'admin', 24 | permission: userPermission.ADMIN 25 | }, 26 | { 27 | id: 1, 28 | username: 'user', 29 | password: 'user', 30 | permission: userPermission.USERS 31 | }, 32 | ]; 33 | 34 | module.exports = { 35 | [`POST /login`] (req, res){ 36 | const { username, password } = req.body 37 | const user = adminUsers.filter((item) => item.username === username) 38 | 39 | if (user.length > 0 && user[0].password === password) { 40 | const now = new Date() 41 | now.setDate(now.getDate() + 1) 42 | res.cookie('token', JSON.stringify({ id: user[0].id, deadline: now.getTime() }), { 43 | maxAge: 900000, 44 | httpOnly: true, 45 | }) 46 | res.json({ success: true, message: 'ok' }) 47 | } else { 48 | res.status(400).end() 49 | } 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/models/example.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | 4 | namespace: 'example', 5 | 6 | state: {}, 7 | 8 | subscriptions: { 9 | setup({ dispatch, history }) { // eslint-disable-line 10 | }, 11 | }, 12 | 13 | effects: { 14 | *fetch({ payload }, { call, put }) { // eslint-disable-line 15 | yield put({ type: 'save' }); 16 | }, 17 | }, 18 | 19 | reducers: { 20 | save(state, action) { 21 | return { ...state, ...action.payload }; 22 | }, 23 | }, 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/models/login.js: -------------------------------------------------------------------------------- 1 | import * as service from '../services/login' 2 | import { routerRedux } from 'dva/router' 3 | 4 | export default { 5 | namespace: 'login', 6 | state: { 7 | loginLoading: false 8 | }, 9 | reducers: { 10 | showLoginLoading(state) { 11 | return { 12 | ...state, 13 | loginLoading: true, 14 | } 15 | }, 16 | hideLoginLoading(state) { 17 | return { 18 | ...state, 19 | loginLoading: false 20 | } 21 | } 22 | }, 23 | effects: { 24 | *login({ payload, }, { call, put }) { 25 | 26 | yield put({ 27 | type: 'showLoginLoading' 28 | }); 29 | const data = yield call(service.login, payload); 30 | 31 | yield put({ 32 | type: 'hideLoginLoading' 33 | }); 34 | if (data.success) { 35 | yield put(routerRedux.push('/index')) 36 | } 37 | } 38 | }, 39 | subscriptions: {}, 40 | }; 41 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route } from 'dva/router'; 3 | import IndexPage from './routes/IndexPage'; 4 | import Login from './routes/Login' 5 | 6 | function RouterConfig({ history }) { 7 | return ( 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | export default RouterConfig; 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/routes/IndexPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import styles from './IndexPage.less'; 4 | 5 | function IndexPage() { 6 | return ( 7 |
8 |

Yay! Welcome to dva!

9 |
10 |
    11 |
  • To get started, edit src/index.js and save to reload.
  • 12 |
  • Getting Started
  • 13 |
14 |
15 | ); 16 | } 17 | 18 | IndexPage.propTypes = { 19 | }; 20 | 21 | export default connect()(IndexPage); 22 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/routes/IndexPage.less: -------------------------------------------------------------------------------- 1 | 2 | .normal { 3 | font-family: Georgia, sans-serif; 4 | margin-top: 3em; 5 | text-align: center; 6 | } 7 | 8 | .title { 9 | font-size: 2.5rem; 10 | font-weight: normal; 11 | letter-spacing: -1px; 12 | } 13 | 14 | .welcome { 15 | height: 328px; 16 | background: url(../assets/yay.jpg) no-repeat center 0; 17 | background-size: 388px 328px; 18 | } 19 | 20 | .list { 21 | font-size: 1.2em; 22 | margin-top: 1.8em; 23 | list-style: none; 24 | line-height: 1.5em; 25 | } 26 | 27 | .list code { 28 | background: #f7f7f7; 29 | } 30 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/routes/Login.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import styles from './Login.less' 4 | import { Form, Icon, Input, Button, Checkbox } from 'antd'; 5 | const FormItem = Form.Item; 6 | 7 | const Login = ({ 8 | dispatch, 9 | login, 10 | form: { 11 | getFieldDecorator, 12 | validateFieldsAndScroll 13 | } 14 | }) => { 15 | const { loginLoading } = login; 16 | 17 | function handelSubmit() { 18 | validateFieldsAndScroll((errors, values) => { 19 | if (errors) { 20 | return; 21 | } 22 | dispatch({ 23 | type: 'login/login', 24 | payload: values, 25 | }); 26 | }); 27 | } 28 | 29 | return ( 30 |
31 |
32 | 33 | {getFieldDecorator('username', { 34 | rules: [{ required: true, message: 'Please input your username!' }], 35 | })( 36 | } placeholder="Username" /> 37 | )} 38 | 39 | 40 | {getFieldDecorator('password', { 41 | rules: [{ required: true, message: 'Please input your Password!' }], 42 | })( 43 | } type="password" placeholder="Password" /> 44 | )} 45 | 46 | 47 | {getFieldDecorator('remember', { 48 | valuePropName: 'checked', 49 | initialValue: true, 50 | })( 51 | Remember me 52 | )} 53 | Forgot password 54 | 57 | Or register now! 58 | 59 |
60 |
61 | ); 62 | }; 63 | 64 | // export default Lists; 65 | export default connect(({ login }) => ({ 66 | login, 67 | }))(Form.create()(Login)); 68 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/routes/Login.less: -------------------------------------------------------------------------------- 1 | .warp { 2 | position: absolute; 3 | top: 50%; 4 | left: 50%; 5 | margin: -160px 0 0 -160px; 6 | width: 320px; 7 | height: 320px; 8 | padding: 36px; 9 | box-shadow: 0 0 100px rgba(0,0,0,.08); 10 | } 11 | .form { 12 | max-width: 320px; 13 | } 14 | .forgot { 15 | float: right; 16 | } 17 | .button { 18 | width: 100%; 19 | } 20 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/services/example.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export async function query() { 4 | return request('/api/users'); 5 | } 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/services/login.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/25. 3 | */ 4 | 5 | import request from '../utils/request' 6 | 7 | export async function login(data) { 8 | return request( { 9 | url: '/login', 10 | method: 'post', 11 | data, 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/login-demo/src/utils/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | baseURL: 'http://localhost:8000/', 3 | }; 4 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "rules": { 5 | "generator-star-spacing": [0], 6 | "consistent-return": [0], 7 | "react/forbid-prop-types": [0], 8 | "react/jsx-filename-extension": [1, { "extensions": [".js"] }], 9 | "global-require": [1], 10 | "import/prefer-default-export": [0], 11 | "react/jsx-no-bind": [0], 12 | "react/prop-types": [0], 13 | "react/prefer-stateless-function": [0], 14 | "no-else-return": [0], 15 | "no-restricted-syntax": [0], 16 | "import/no-extraneous-dependencies": [0], 17 | "no-use-before-define": [0], 18 | "jsx-a11y/no-static-element-interactions": [0], 19 | "no-nested-ternary": [0], 20 | "arrow-body-style": [0], 21 | "import/extensions": [0], 22 | "no-bitwise": [0], 23 | "no-cond-assign": [0], 24 | "import/no-unresolved": [0], 25 | "require-yield": [1], 26 | "quotes": ["error", "single", { "allowTemplateLiterals": true }] 27 | }, 28 | "parserOptions": { 29 | "ecmaFeatures": { 30 | "experimentalObjectRestSpread": true 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # production 7 | /dist 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log* 12 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/.roadhogrc: -------------------------------------------------------------------------------- 1 | { 2 | "entry": "src/index.js", 3 | "env": { 4 | "development": { 5 | "extraBabelPlugins": [ 6 | "dva-hmr", 7 | "transform-runtime", 8 | ["import", { "libraryName": "antd", "style": "css" }] 9 | ] 10 | }, 11 | "production": { 12 | "extraBabelPlugins": [ 13 | "transform-runtime", 14 | ["import", { "libraryName": "antd", "style": "css" }] 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/.roadhogrc.mock.js: -------------------------------------------------------------------------------- 1 | const mock = require('./src/mock/mock') 2 | 3 | module.exports = mock 4 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "roadhog server", 5 | "build": "roadhog build", 6 | "lint": "eslint --ext .js src test", 7 | "precommit": "npm run lint" 8 | }, 9 | "engines": { 10 | "install-node": "6.9.2" 11 | }, 12 | "dependencies": { 13 | "antd": "^2.10.2", 14 | "axios": "^0.16.1", 15 | "babel-plugin-import": "^1.2.0", 16 | "babel-runtime": "^6.9.2", 17 | "dva": "^1.2.1", 18 | "mockjs": "^1.0.1-beta3", 19 | "react": "^15.4.0", 20 | "react-dom": "^15.4.0" 21 | }, 22 | "devDependencies": { 23 | "babel-eslint": "^7.1.1", 24 | "babel-plugin-dva-hmr": "^0.3.2", 25 | "babel-plugin-transform-runtime": "^6.9.0", 26 | "eslint": "^3.12.2", 27 | "eslint-config-airbnb": "^13.0.0", 28 | "eslint-plugin-import": "^2.2.0", 29 | "eslint-plugin-jsx-a11y": "^2.2.3", 30 | "eslint-plugin-react": "^6.8.0", 31 | "expect": "^1.20.2", 32 | "husky": "^0.12.0", 33 | "redbox-react": "^1.3.2", 34 | "roadhog": "^0.5.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dva Demo 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/higher-demo/dva-antd/mockjs-demo/src/assets/yay.jpg -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/components/Example.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Example = () => { 4 | return ( 5 |
6 | Example 7 |
8 | ); 9 | }; 10 | 11 | Example.propTypes = { 12 | }; 13 | 14 | export default Example; 15 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/components/List.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/23. 3 | */ 4 | import React from 'react'; 5 | import PropTypes from 'prop-types'; 6 | import { Table } from 'antd'; 7 | 8 | const List = ({ index }) => { 9 | const columns = [ 10 | { 11 | title: 'Name', 12 | dataIndex: 'name', 13 | }, 14 | { 15 | title: 'age', 16 | dataIndex: 'age', 17 | }, 18 | { 19 | title: 'color', 20 | dataIndex: 'color', 21 | }, 22 | ]; 23 | 24 | 25 | 26 | 27 | return ( 28 | 33 | ); 34 | }; 35 | 36 | List.propTypes = { 37 | index: PropTypes.array.isRequired, 38 | }; 39 | 40 | export default List; 41 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/index.css: -------------------------------------------------------------------------------- 1 | 2 | html, body, :global(#root) { 3 | height: 100%; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/index.js: -------------------------------------------------------------------------------- 1 | import dva from 'dva'; 2 | import './index.css'; 3 | 4 | // 1. Initialize 5 | const app = dva(); 6 | 7 | // 2. Plugins 8 | // app.use({}); 9 | 10 | // 3. Model 11 | app.model(require('./models/index')); 12 | 13 | // 4. Router 14 | app.router(require('./router')); 15 | 16 | // 5. Start 17 | app.start('#root'); 18 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/mock/mock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/25. 3 | */ 4 | const Mock = require('mockjs'); 5 | 6 | const data = Mock.mock({ 7 | 'users|10-20': [ 8 | { 9 | name: '@name', 10 | 'age|1-100': 100, 11 | color: '@color', 12 | }, 13 | ], 14 | }); 15 | 16 | const database = data.users; 17 | 18 | module.exports = { 19 | [`GET /users`](req, res) { 20 | res.status(200).json(database); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/models/index.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | 4 | namespace: 'index', 5 | 6 | state: [], 7 | 8 | subscriptions: { 9 | setup({ dispatch, history }) { // eslint-disable-line 10 | }, 11 | }, 12 | 13 | effects: { 14 | *fetch({ payload }, { call, put }) { // eslint-disable-line 15 | yield put({ type: 'save' }); 16 | }, 17 | }, 18 | 19 | reducers: { 20 | save(state, action) { 21 | return [...state, ...action.payload]; 22 | }, 23 | }, 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route } from 'dva/router'; 3 | import IndexPage from './routes/IndexPage'; 4 | 5 | function RouterConfig({ history }) { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | export default RouterConfig; 14 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/routes/IndexPage.css: -------------------------------------------------------------------------------- 1 | 2 | .normal { 3 | font-family: Georgia, sans-serif; 4 | margin-top: 3em; 5 | text-align: center; 6 | } 7 | 8 | .title { 9 | font-size: 2.5rem; 10 | font-weight: normal; 11 | letter-spacing: -1px; 12 | } 13 | 14 | .welcome { 15 | height: 328px; 16 | background: url(../assets/yay.jpg) no-repeat center 0; 17 | background-size: 388px 328px; 18 | } 19 | 20 | .list { 21 | font-size: 1.2em; 22 | margin-top: 1.8em; 23 | list-style: none; 24 | line-height: 1.5em; 25 | } 26 | 27 | .list code { 28 | background: #f7f7f7; 29 | } 30 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/routes/IndexPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import { Button } from 'antd'; 4 | import request from '../utils/request'; 5 | import List from '../components/List'; 6 | 7 | 8 | const IndexPage = ({ dispatch, index }) => { 9 | function click() { 10 | request('/users').then((result) => { 11 | dispatch({ 12 | type: 'index/save', 13 | payload: result, 14 | }); 15 | }); 16 | } 17 | 18 | return ( 19 |
20 | 21 | 22 |
23 | ); 24 | }; 25 | 26 | IndexPage.propTypes = { 27 | }; 28 | 29 | export default connect(({ index }) => ({ 30 | index, 31 | }))(IndexPage); 32 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/services/example.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export async function query() { 4 | return request('/api/users'); 5 | } 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/mockjs-demo/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import fetch from 'dva/fetch'; 2 | 3 | function checkStatus(response) { 4 | if (response.status >= 200 && response.status < 300) { 5 | return response; 6 | } 7 | 8 | const error = new Error(response.statusText); 9 | error.response = response; 10 | throw error; 11 | } 12 | 13 | /** 14 | * Requests a URL, returning a promise. 15 | * 16 | * @param {string} url The URL we want to request 17 | * @param {object} [options] The options we want to pass to "fetch" 18 | * @return {object} An object containing either "data" or "err" 19 | */ 20 | export default async function request(url, options) { 21 | const response = await fetch(url, options); 22 | 23 | checkStatus(response); 24 | 25 | const data = await response.json(); 26 | 27 | const ret = { 28 | data, 29 | headers: {}, 30 | }; 31 | 32 | if (response.headers.get('x-total-count')) { 33 | ret.headers['x-total-count'] = response.headers.get('x-total-count'); 34 | } 35 | return ret.data; 36 | } 37 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "rules": { 5 | "generator-star-spacing": [0], 6 | "consistent-return": [0], 7 | "react/forbid-prop-types": [0], 8 | "react/jsx-filename-extension": [1, { "extensions": [".js"] }], 9 | "global-require": [1], 10 | "import/prefer-default-export": [0], 11 | "react/jsx-no-bind": [0], 12 | "react/prop-types": [0], 13 | "react/prefer-stateless-function": [0], 14 | "no-else-return": [0], 15 | "no-restricted-syntax": [0], 16 | "import/no-extraneous-dependencies": [0], 17 | "no-use-before-define": [0], 18 | "jsx-a11y/no-static-element-interactions": [0], 19 | "no-nested-ternary": [0], 20 | "arrow-body-style": [0], 21 | "import/extensions": [0], 22 | "no-bitwise": [0], 23 | "no-cond-assign": [0], 24 | "import/no-unresolved": [0], 25 | "require-yield": [1] 26 | }, 27 | "parserOptions": { 28 | "ecmaFeatures": { 29 | "experimentalObjectRestSpread": true 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # production 7 | /dist 8 | 9 | # misc 10 | .DS_Store 11 | npm-debug.log* 12 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/.roadhogrc: -------------------------------------------------------------------------------- 1 | { 2 | "entry": "src/index.js", 3 | "env": { 4 | "development": { 5 | "extraBabelPlugins": [ 6 | "dva-hmr", 7 | "transform-runtime", 8 | ["import", { "libraryName": "antd", "style": "css" }] 9 | ] 10 | }, 11 | "production": { 12 | "extraBabelPlugins": [ 13 | "transform-runtime", 14 | ["import", { "libraryName": "antd", "style": "css" }] 15 | ] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/.roadhogrc.mock.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | }; 4 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/mock/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/higher-demo/dva-antd/todo-list/mock/.gitkeep -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "roadhog server", 5 | "build": "roadhog build", 6 | "lint": "eslint --ext .js src test", 7 | "precommit": "npm run lint" 8 | }, 9 | "engines": { 10 | "install-node": "6.9.2" 11 | }, 12 | "dependencies": { 13 | "antd": "^2.10.2", 14 | "babel-plugin-import": "^1.1.1", 15 | "babel-runtime": "^6.9.2", 16 | "dva": "^1.2.1", 17 | "react": "^15.4.0", 18 | "react-dom": "^15.4.0" 19 | }, 20 | "devDependencies": { 21 | "babel-eslint": "^7.1.1", 22 | "babel-plugin-dva-hmr": "^0.3.2", 23 | "babel-plugin-transform-runtime": "^6.9.0", 24 | "eslint": "^3.12.2", 25 | "eslint-config-airbnb": "^13.0.0", 26 | "eslint-plugin-import": "^2.2.0", 27 | "eslint-plugin-jsx-a11y": "^2.2.3", 28 | "eslint-plugin-react": "^6.8.0", 29 | "expect": "^1.20.2", 30 | "husky": "^0.12.0", 31 | "redbox-react": "^1.3.2", 32 | "roadhog": "^0.5.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dva Demo 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/assets/yay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/higher-demo/dva-antd/todo-list/src/assets/yay.jpg -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/components/Add.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/24. 3 | */ 4 | import React from 'react'; 5 | import PropTypes from 'prop-types'; 6 | import { Input, Icon, Button } from 'antd'; 7 | 8 | 9 | const Add = ({ onAdd, onChange, input }) => { 10 | return ( 11 |
12 | } 15 | value={input} 16 | onChange={onChange} 17 | /> 18 | 19 |
20 | ); 21 | }; 22 | 23 | Add.propTypes = { 24 | onAdd: PropTypes.func.isRequired, 25 | input: PropTypes.string.isRequired, 26 | }; 27 | 28 | export default Add; 29 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/components/Example.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Example = () => { 4 | return ( 5 |
6 | Example 7 |
8 | ); 9 | }; 10 | 11 | Example.propTypes = { 12 | }; 13 | 14 | export default Example; 15 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/components/List.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/23. 3 | */ 4 | import React from 'react'; 5 | import PropTypes from 'prop-types'; 6 | import { Table, Popconfirm, Button } from 'antd'; 7 | 8 | const List = ({ onDelete, lists }) => { 9 | const columns = [ 10 | { 11 | title: 'Id', 12 | dataIndex: 'id', 13 | }, 14 | { 15 | title: 'Name', 16 | dataIndex: 'name', 17 | }, 18 | { 19 | title: 'Actions', 20 | render: (text, record) => { 21 | return ( 22 | onDelete(record.id)}> 23 | 24 | 25 | ); 26 | }, 27 | }, 28 | ]; 29 | return ( 30 |
35 | ); 36 | }; 37 | 38 | List.propTypes = { 39 | onDelete: PropTypes.func.isRequired, 40 | lists: PropTypes.array.isRequired, 41 | }; 42 | 43 | export default List; 44 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/index.css: -------------------------------------------------------------------------------- 1 | 2 | html, body, :global(#root) { 3 | height: 100%; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/index.js: -------------------------------------------------------------------------------- 1 | import dva from 'dva'; 2 | import './index.css'; 3 | 4 | // 1. Initialize 5 | const app = dva({ 6 | initialState: { 7 | lists: [ 8 | { name: 'dva', id: 1 }, 9 | { name: 'antd', id: 2 }, 10 | ], 11 | }, 12 | }); 13 | 14 | app.model(require('./models/list')); 15 | app.model(require('./models/add')); 16 | 17 | // 2. Plugins 18 | // app.use({}); 19 | 20 | // 3. Model 21 | // app.model(require('./models/example')); 22 | 23 | // 4. Router 24 | app.router(require('./router')); 25 | 26 | // 5. Start 27 | app.start('#root'); 28 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/models/add.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/5/24. 3 | */ 4 | export default { 5 | namespace: 'inputs', 6 | state: { 7 | input: 'name', 8 | }, 9 | reducers: { 10 | change(state, { payload: name }) { 11 | return { input: name }; 12 | }, 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/models/example.js: -------------------------------------------------------------------------------- 1 | 2 | export default { 3 | 4 | namespace: 'example', 5 | 6 | state: {}, 7 | 8 | subscriptions: { 9 | setup({ dispatch, history }) { // eslint-disable-line 10 | }, 11 | }, 12 | 13 | effects: { 14 | *fetch({ payload }, { call, put }) { // eslint-disable-line 15 | yield put({ type: 'save' }); 16 | }, 17 | }, 18 | 19 | reducers: { 20 | save(state, action) { 21 | return { ...state, ...action.payload }; 22 | }, 23 | }, 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/models/list.js: -------------------------------------------------------------------------------- 1 | export default { 2 | namespace: 'lists', 3 | state: [], 4 | reducers: { 5 | add(state, { payload: name }) { 6 | let id = state.reduce( 7 | (previous, current) => (previous.id > current.id ? previous : current), 8 | ).id; 9 | id += 1; 10 | return [...state, { name, id }]; 11 | }, 12 | delete(state, { payload: id }) { 13 | return state.filter(item => item.id !== id); 14 | }, 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route } from 'dva/router'; 3 | import IndexPage from './routes/IndexPage'; 4 | 5 | import List from './routes/List.js'; 6 | 7 | function RouterConfig({ history }) { 8 | return ( 9 | 10 | 11 | 12 | 13 | ); 14 | } 15 | 16 | export default RouterConfig; 17 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/routes/IndexPage.css: -------------------------------------------------------------------------------- 1 | 2 | .normal { 3 | font-family: Georgia, sans-serif; 4 | margin-top: 3em; 5 | text-align: center; 6 | } 7 | 8 | .title { 9 | font-size: 2.5rem; 10 | font-weight: normal; 11 | letter-spacing: -1px; 12 | } 13 | 14 | .welcome { 15 | height: 328px; 16 | background: url(../assets/yay.jpg) no-repeat center 0; 17 | background-size: 388px 328px; 18 | } 19 | 20 | .list { 21 | font-size: 1.2em; 22 | margin-top: 1.8em; 23 | list-style: none; 24 | line-height: 1.5em; 25 | } 26 | 27 | .list code { 28 | background: #f7f7f7; 29 | } 30 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/routes/IndexPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import styles from './IndexPage.css'; 4 | 5 | function IndexPage() { 6 | return ( 7 |
8 |

Yay! Welcome to dva!

9 |
10 |
    11 |
  • To get started, edit src/index.js and save to reload.
  • 12 |
  • Getting Started
  • 13 |
14 |
15 | ); 16 | } 17 | 18 | IndexPage.propTypes = { 19 | }; 20 | 21 | export default connect()(IndexPage); 22 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/routes/List.css: -------------------------------------------------------------------------------- 1 | 2 | .normal { 3 | } 4 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/routes/List.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'dva'; 3 | import List from '../components/List'; 4 | import Add from '../components/Add'; 5 | 6 | const Lists = ({ dispatch, lists, inputs }) => { 7 | function handleDelete(id) { 8 | dispatch({ 9 | type: 'lists/delete', 10 | payload: id, 11 | }); 12 | } 13 | function handleAdd() { 14 | dispatch({ 15 | type: 'lists/add', 16 | payload: inputs.input, 17 | }); 18 | } 19 | 20 | function handelChange(e) { 21 | dispatch({ 22 | type: 'inputs/change', 23 | payload: e.target.value, 24 | }); 25 | } 26 | return ( 27 |
28 | 29 |
30 |
31 |

List of Products

32 |
33 | 34 |
35 | ); 36 | }; 37 | 38 | // export default Lists; 39 | export default connect(({ inputs, lists }) => ({ 40 | inputs, lists, 41 | }))(Lists); 42 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/services/example.js: -------------------------------------------------------------------------------- 1 | import request from '../utils/request'; 2 | 3 | export async function query() { 4 | return request('/api/users'); 5 | } 6 | -------------------------------------------------------------------------------- /higher-demo/dva-antd/todo-list/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import fetch from 'dva/fetch'; 2 | 3 | function parseJSON(response) { 4 | return response.json(); 5 | } 6 | 7 | function checkStatus(response) { 8 | if (response.status >= 200 && response.status < 300) { 9 | return response; 10 | } 11 | 12 | const error = new Error(response.statusText); 13 | error.response = response; 14 | throw error; 15 | } 16 | 17 | /** 18 | * Requests a URL, returning a promise. 19 | * 20 | * @param {string} url The URL we want to request 21 | * @param {object} [options] The options we want to pass to "fetch" 22 | * @return {object} An object containing either "data" or "err" 23 | */ 24 | export default function request(url, options) { 25 | return fetch(url, options) 26 | .then(checkStatus) 27 | .then(parseJSON) 28 | .then(data => ({ data })) 29 | .catch(err => ({ err })); 30 | } 31 | -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react", 5 | "stage-0" 6 | ], 7 | "plugins": [ 8 | "react-hot-loader/babel" 9 | ] 10 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/README.md: -------------------------------------------------------------------------------- 1 | ## todo list -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/dist/api/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "brickspert", 3 | "intro": "please give me a star" 4 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-all-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev-build": "webpack --config webpack.dev.config.js", 9 | "start": "webpack-dev-server --config webpack.dev.config.js", 10 | "dev": "webpack-dev-server --config webpack.dev.config.js --color --progress --hot" 11 | }, 12 | "author": "", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "babel-core": "^6.26.0", 16 | "babel-loader": "^7.1.2", 17 | "babel-preset-es2015": "^6.24.1", 18 | "babel-preset-react": "^6.24.1", 19 | "babel-preset-stage-0": "^6.24.1", 20 | "css-loader": "^0.28.7", 21 | "react-hot-loader": "^3.0.0", 22 | "style-loader": "^0.19.1", 23 | "webpack": "^3.10.0", 24 | "webpack-dev-server": "^2.9.7" 25 | }, 26 | "dependencies": { 27 | "react": "^16.2.0", 28 | "react-dom": "^16.2.0", 29 | "react-redux": "^5.0.6", 30 | "react-router-dom": "^4.2.2", 31 | "redux": "^3.7.2", 32 | "redux-thunk": "^2.2.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/component/Hello/Hello.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | Component 3 | } from 'react'; 4 | 5 | export default class Hello extends Component { 6 | render() { 7 | return ( 8 |
9 | Hello, React! 10 |
11 | ) 12 | } 13 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import {AppContainer} from 'react-hot-loader'; 4 | import {Provider} from 'react-redux'; 5 | import store from './redux/store'; 6 | 7 | import getRouter from 'router/router'; 8 | 9 | /*初始化*/ 10 | renderWithHotReload(getRouter()); 11 | 12 | /*热更新*/ 13 | if (module.hot) { 14 | module.hot.accept('./router/router', () => { 15 | const getRouter = require('router/router').default; 16 | renderWithHotReload(getRouter()); 17 | }); 18 | } 19 | 20 | function renderWithHotReload(RootElement) { 21 | ReactDom.render( 22 | 23 | 24 | {RootElement} 25 | 26 | , 27 | document.getElementById('app') 28 | ) 29 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/pages/Counter/Counter.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {increment, decrement, reset} from 'actions/counter'; 3 | 4 | import {connect} from 'react-redux'; 5 | 6 | class Counter extends Component { 7 | render() { 8 | return ( 9 |
10 |
当前计数为{this.props.counter.count}
11 | 13 | 15 | 17 |
18 | ) 19 | } 20 | } 21 | 22 | const mapStateToProps = (state) => { 23 | return { 24 | counter: state.counter 25 | } 26 | }; 27 | 28 | const mapDispatchToProps = (dispatch) => { 29 | return { 30 | increment: () => { 31 | dispatch(increment()) 32 | }, 33 | decrement: () => { 34 | dispatch(decrement()) 35 | }, 36 | reset: () => { 37 | dispatch(reset()) 38 | } 39 | } 40 | }; 41 | 42 | export default connect(mapStateToProps, mapDispatchToProps)(Counter); -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/pages/Home/Home.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | 3 | export default class Home extends Component { 4 | render() { 5 | return ( 6 |
7 | this is home~ 8 |
9 | ) 10 | } 11 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/pages/Page1/Page1.css: -------------------------------------------------------------------------------- 1 | .page-box { 2 | border: 1px solid red; 3 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/pages/Page1/Page1.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | 3 | import './Page1.css'; 4 | 5 | export default class Page1 extends Component { 6 | render() { 7 | return ( 8 |
9 | this is page1~ 10 |
11 | ) 12 | } 13 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/pages/UserInfo/UserInfo.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {connect} from 'react-redux'; 3 | import {getUserInfo} from "actions/userInfo"; 4 | 5 | class UserInfo extends Component { 6 | 7 | render() { 8 | const {userInfo, isLoading, errorMsg} = this.props.userInfo; 9 | return ( 10 |
11 | { 12 | isLoading ? '请求信息中......' : 13 | ( 14 | errorMsg ? errorMsg : 15 |
16 |

用户信息:

17 |

用户名:{userInfo.name}

18 |

介绍:{userInfo.intro}

19 |
20 | ) 21 | } 22 | 23 |
24 | ) 25 | } 26 | } 27 | 28 | export default connect((state) => ({userInfo: state.userInfo}), {getUserInfo})(UserInfo); 29 | -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/actions/counter.js: -------------------------------------------------------------------------------- 1 | /*action*/ 2 | 3 | export const INCREMENT = "counter/INCREMENT"; 4 | export const DECREMENT = "counter/DECREMENT"; 5 | export const RESET = "counter/RESET"; 6 | 7 | export function increment() { 8 | return {type: INCREMENT} 9 | } 10 | 11 | export function decrement() { 12 | return {type: DECREMENT} 13 | } 14 | 15 | export function reset() { 16 | return {type: RESET} 17 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/actions/userInfo.js: -------------------------------------------------------------------------------- 1 | export const GET_USER_INFO_REQUEST = "userInfo/GET_USER_INFO_REQUEST"; 2 | export const GET_USER_INFO_SUCCESS = "userInfo/GET_USER_INFO_SUCCESS"; 3 | export const GET_USER_INFO_FAIL = "userInfo/GET_USER_INFO_FAIL"; 4 | 5 | function getUserInfoRequest() { 6 | return { 7 | type: GET_USER_INFO_REQUEST 8 | } 9 | } 10 | 11 | function getUserInfoSuccess(userInfo) { 12 | return { 13 | type: GET_USER_INFO_SUCCESS, 14 | userInfo: userInfo 15 | } 16 | } 17 | 18 | function getUserInfoFail() { 19 | return { 20 | type: GET_USER_INFO_FAIL 21 | } 22 | } 23 | 24 | export function getUserInfo() { 25 | return function (dispatch) { 26 | dispatch(getUserInfoRequest()); 27 | 28 | return fetch('http://localhost:8080/api/user.json') 29 | .then((response => { 30 | return response.json() 31 | })) 32 | .then((json) => { 33 | dispatch(getUserInfoSuccess(json)) 34 | } 35 | ).catch( 36 | () => { 37 | dispatch(getUserInfoFail()); 38 | } 39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/reducers.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from "redux"; 2 | 3 | import counter from 'reducers/counter'; 4 | import userInfo from 'reducers/userInfo'; 5 | 6 | 7 | export default combineReducers({ 8 | counter, 9 | userInfo 10 | }); -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/reducers/counter.js: -------------------------------------------------------------------------------- 1 | import {INCREMENT, DECREMENT, RESET} from '../actions/counter'; 2 | 3 | /* 4 | * 初始化state 5 | */ 6 | 7 | const initState = { 8 | count: 0 9 | }; 10 | /* 11 | * reducer 12 | */ 13 | export default function reducer(state = initState, action) { 14 | switch (action.type) { 15 | case INCREMENT: 16 | return { 17 | count: state.count + 1 18 | }; 19 | case DECREMENT: 20 | return { 21 | count: state.count - 1 22 | }; 23 | case RESET: 24 | return {count: 0}; 25 | default: 26 | return state 27 | } 28 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/reducers/userInfo.js: -------------------------------------------------------------------------------- 1 | import {GET_USER_INFO_REQUEST, GET_USER_INFO_SUCCESS, GET_USER_INFO_FAIL} from 'actions/userInfo'; 2 | 3 | 4 | const initState = { 5 | isLoading: false, 6 | userInfo: {}, 7 | errorMsg: '' 8 | }; 9 | 10 | export default function reducer(state = initState, action) { 11 | switch (action.type) { 12 | case GET_USER_INFO_REQUEST: 13 | return { 14 | ...state, 15 | isLoading: true, 16 | userInfo: {}, 17 | errorMsg: '' 18 | }; 19 | case GET_USER_INFO_SUCCESS: 20 | return { 21 | ...state, 22 | isLoading: false, 23 | userInfo: action.userInfo, 24 | errorMsg: '' 25 | }; 26 | case GET_USER_INFO_FAIL: 27 | return { 28 | ...state, 29 | isLoading: false, 30 | userInfo: {}, 31 | errorMsg: '请求错误' 32 | }; 33 | default: 34 | return state; 35 | } 36 | } -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/store.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware} from 'redux'; 2 | import thunkMiddleware from 'redux-thunk'; 3 | import combineReducers from './reducers.js'; 4 | 5 | let store = createStore(combineReducers, applyMiddleware(thunkMiddleware)); 6 | 7 | export default store; -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/redux/testRedux.js: -------------------------------------------------------------------------------- 1 | import {increment, decrement, reset} from './actions/counter'; 2 | 3 | import store from './store'; 4 | 5 | // 打印初始状态 6 | console.log(store.getState()); 7 | 8 | // 每次 state 更新时,打印日志 9 | // 注意 subscribe() 返回一个函数用来注销监听器 10 | let unsubscribe = store.subscribe(() => 11 | console.log(store.getState()) 12 | ); 13 | 14 | // 发起一系列 action 15 | store.dispatch(increment()); 16 | store.dispatch(decrement()); 17 | store.dispatch(reset()); 18 | 19 | // 停止监听 state 更新 20 | unsubscribe(); -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/src/router/router.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {BrowserRouter as Router, Route, Switch, Link} from 'react-router-dom'; 4 | 5 | import Home from 'pages/Home/Home'; 6 | import Page1 from 'pages/Page1/Page1'; 7 | import Counter from 'pages/Counter/Counter'; 8 | import UserInfo from 'pages/UserInfo/UserInfo'; 9 | 10 | const getRouter = () => ( 11 | 12 |
13 |
    14 |
  • 首页
  • 15 |
  • Page1
  • 16 |
  • Counter
  • 17 |
  • UserInfo
  • 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | ); 28 | 29 | export default getRouter; -------------------------------------------------------------------------------- /higher-demo/react-all/react-all-demo/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: path.join(__dirname, 'src/index.js'), 5 | 6 | output: { 7 | path: path.join(__dirname, './dist'), 8 | filename: 'bundle.js' 9 | }, 10 | module: { 11 | rules: [{ 12 | test: /\.js$/, 13 | use: ['babel-loader?cacheDirectory=true'], 14 | include: path.join(__dirname, 'src') 15 | },{ 16 | test: /\.css$/, 17 | use: ['style-loader', 'css-loader'] 18 | }] 19 | }, 20 | devServer: { 21 | port: 8080, 22 | contentBase: path.join(__dirname, './dist'), 23 | historyApiFallback: true, 24 | host: '0.0.0.0' 25 | }, 26 | entry: [ 27 | 'react-hot-loader/patch', 28 | path.join(__dirname, 'src/index.js') 29 | ], 30 | resolve: { 31 | alias: { 32 | pages: path.join(__dirname, 'src/pages'), 33 | component: path.join(__dirname, 'src/component'), 34 | router: path.join(__dirname, 'src/router'), 35 | actions: path.join(__dirname, 'src/redux/actions'), 36 | reducers: path.join(__dirname, 'src/redux/reducers'), 37 | } 38 | }, 39 | devtool: 'inline-source-map' 40 | } -------------------------------------------------------------------------------- /higher-demo/redux/todolist/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/README.md: -------------------------------------------------------------------------------- 1 | ## todo list -------------------------------------------------------------------------------- /higher-demo/redux/todolist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todolist", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^15.5.4", 7 | "react-dom": "^15.5.4", 8 | "react-redux": "^5.0.5", 9 | "react-router": "^4.1.1", 10 | "redux": "^3.6.0" 11 | }, 12 | "devDependencies": { 13 | "react-scripts": "1.0.7" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "test": "react-scripts test --env=jsdom", 19 | "eject": "react-scripts eject" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/higher-demo/redux/todolist/public/favicon.ico -------------------------------------------------------------------------------- /higher-demo/redux/todolist/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-intro { 18 | font-size: large; 19 | } 20 | 21 | @keyframes App-logo-spin { 22 | from { transform: rotate(0deg); } 23 | to { transform: rotate(360deg); } 24 | } 25 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | }); 9 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/components/AddTodo.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | 3 | export default class AddTodo extends Component { 4 | render() { 5 | return ( 6 |
7 | 8 | 11 |
12 | ) 13 | } 14 | 15 | handleClick(e) { 16 | const node = this.refs.input 17 | const text = node.value.trim() 18 | this.props.onAddClick(text) 19 | node.value = '' 20 | } 21 | } 22 | 23 | AddTodo.propTypes = { 24 | onAddClick: PropTypes.func.isRequired 25 | } -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | 3 | export default class Footer extends Component { 4 | renderFilter(filter, name) { 5 | if (filter === this.props.filter) { 6 | return name 7 | } 8 | 9 | return ( 10 | { 11 | e.preventDefault() 12 | this.props.onFilterChange(filter) 13 | }}> 14 | {name} 15 | 16 | ) 17 | } 18 | 19 | render() { 20 | return ( 21 |

22 | Show: 23 | {' '} 24 | {this.renderFilter('SHOW_ALL', 'All')} 25 | {', '} 26 | {this.renderFilter('SHOW_COMPLETED', 'Completed')} 27 | {', '} 28 | {this.renderFilter('SHOW_ACTIVE', 'Active')} 29 | . 30 |

31 | ) 32 | } 33 | } 34 | 35 | Footer.propTypes = { 36 | onFilterChange: PropTypes.func.isRequired, 37 | filter: PropTypes.oneOf([ 38 | 'SHOW_ALL', 39 | 'SHOW_COMPLETED', 40 | 'SHOW_ACTIVE' 41 | ]).isRequired 42 | } -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/components/Todo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/6/6. 3 | */ 4 | import React, { Component, PropTypes } from 'react' 5 | 6 | export default class Todo extends Component { 7 | render() { 8 | return ( 9 |
  • 15 | {this.props.text} 16 |
  • 17 | ) 18 | } 19 | } 20 | 21 | Todo.propTypes = { 22 | onClick: PropTypes.func.isRequired, 23 | text: PropTypes.string.isRequired, 24 | completed: PropTypes.bool.isRequired 25 | } -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/components/TodoList.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import Todo from './Todo' 3 | 4 | export default class TodoList extends Component { 5 | render() { 6 | return ( 7 |
      8 | {this.props.todos.map((todo, index) => 9 | this.props.onTodoClick(index)} /> 12 | )} 13 |
    14 | ) 15 | } 16 | } 17 | 18 | TodoList.propTypes = { 19 | onTodoClick: PropTypes.func.isRequired, 20 | todos: PropTypes.arrayOf(PropTypes.shape({ 21 | text: PropTypes.string.isRequired, 22 | completed: PropTypes.bool.isRequired 23 | }).isRequired).isRequired 24 | } -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { createStore } from 'redux' 4 | import { Provider } from 'react-redux' 5 | import App from './App'; 6 | import registerServiceWorker from './registerServiceWorker'; 7 | import './index.css'; 8 | import todoApp from './redux/reducers' 9 | let store = createStore(todoApp) 10 | let rootElement = document.getElementById('root') 11 | ReactDOM.render( 12 | 13 | 14 | , 15 | rootElement 16 | ) 17 | 18 | // ReactDOM.render(, document.getElementById('root')); 19 | registerServiceWorker(); 20 | -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/redux/actions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/6/6. 3 | */ 4 | 5 | export const ADD_TODO = 'ADD-TODO'; 6 | export const COMPLETE_TODO = 'COMPLETE_TODO'; 7 | export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER' 8 | 9 | export const VisibilityFilters = { 10 | SHOW_ALL: 'SHOW_ALL', 11 | SHOW_COMPLETED: 'SHOW_COMPLETED', 12 | SHOW_ACTIVE: 'SHOW_ACTIVE' 13 | }; 14 | 15 | /* 16 | * action 创建函数 17 | */ 18 | 19 | export function addTodo(text) { 20 | return { type: ADD_TODO, text } 21 | } 22 | 23 | export function completeTodo(index) { 24 | return { type: COMPLETE_TODO, index } 25 | } 26 | 27 | export function setVisibilityFilter(filter) { 28 | return { type: SET_VISIBILITY_FILTER, filter } 29 | } -------------------------------------------------------------------------------- /higher-demo/redux/todolist/src/redux/reducers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by chengfan on 2017/6/6. 3 | */ 4 | import { combineReducers } from 'redux' 5 | import { ADD_TODO, COMPLETE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from './actions' 6 | const { SHOW_ALL } = VisibilityFilters 7 | 8 | function visibilityFilter(state = SHOW_ALL, action) { 9 | switch (action.type) { 10 | case SET_VISIBILITY_FILTER: 11 | return action.filter 12 | default: 13 | return state 14 | } 15 | } 16 | 17 | function todos(state = [], action) { 18 | switch (action.type) { 19 | case ADD_TODO: 20 | return [ 21 | ...state, 22 | { 23 | text: action.text, 24 | completed: false 25 | } 26 | ] 27 | case COMPLETE_TODO: 28 | return [ 29 | ...state.slice(0, action.index), 30 | Object.assign({}, state[action.index], { 31 | completed: true 32 | }), 33 | ...state.slice(action.index + 1) 34 | ] 35 | default: 36 | return state 37 | } 38 | } 39 | 40 | const todoApp = combineReducers({ 41 | visibilityFilter, 42 | todos 43 | }) 44 | 45 | export default todoApp -------------------------------------------------------------------------------- /middle-demo/comment-app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /middle-demo/comment-app/README.md: -------------------------------------------------------------------------------- 1 | ## 留言板 -------------------------------------------------------------------------------- /middle-demo/comment-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "comment-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.2.0", 7 | "react-dom": "^16.2.0", 8 | "react-scripts": "1.0.17" 9 | }, 10 | "scripts": { 11 | "start": "react-scripts start", 12 | "build": "react-scripts build", 13 | "test": "react-scripts test --env=jsdom", 14 | "eject": "react-scripts eject" 15 | } 16 | } -------------------------------------------------------------------------------- /middle-demo/comment-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sharember/react-demo-gather/e5230987764dfd304a3bf4070c33a5ff1d938921/middle-demo/comment-app/public/favicon.ico -------------------------------------------------------------------------------- /middle-demo/comment-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
    29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /middle-demo/comment-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /middle-demo/comment-app/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /middle-demo/comment-app/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import CommentInput from './CommentInput' 3 | import CommentList from './CommentList' 4 | import './App.css'; 5 | 6 | class App extends Component { 7 | constructor() { 8 | super() 9 | this.state = { 10 | comments: [], 11 | } 12 | } 13 | handleSubmit = (comment) => { 14 | this.setState({ comments: [...this.state.comments, comment] }, () => { 15 | console.log(this.state.comments) 16 | }); 17 | } 18 | render() { 19 | return ( 20 |
    21 | 24 | 27 |
    28 | ); 29 | } 30 | } 31 | 32 | export default App; 33 | -------------------------------------------------------------------------------- /middle-demo/comment-app/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | }); 9 | -------------------------------------------------------------------------------- /middle-demo/comment-app/src/Comment.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import './index.css' 3 | 4 | class Comment extends Component { 5 | render () { 6 | return ( 7 |
    8 |
    9 | {this.props.comment.username} : 10 |

    {this.props.comment.content}

    11 |
    12 |
    13 | ) 14 | } 15 | } 16 | export default Comment -------------------------------------------------------------------------------- /middle-demo/comment-app/src/CommentInput.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class CommentInput extends Component { 4 | constructor() { 5 | super(); 6 | this.state = { 7 | username: '', 8 | content: '' 9 | } 10 | } 11 | 12 | handleUsernameChange (e) { 13 | this.setState({ 14 | username: e.target.value 15 | }) 16 | } 17 | 18 | handleContentChange(e) { 19 | this.setState({ 20 | content: e.target.value 21 | }) 22 | } 23 | 24 | handleSubmit(e) { 25 | if (this.props.onSubmit) { 26 | const { username, content } = this.state 27 | this.props.onSubmit({username, content}) 28 | } 29 | this.setState({ content: '' }) 30 | } 31 | 32 | render() { 33 | return ( 34 |
    35 |
    36 | 用户名: 37 |
    38 | 42 |
    43 |
    44 |
    45 | 评论内容: 46 |
    47 |