├── .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 |
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 |
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 |
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Login/LoginTab.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import PropTypes from 'prop-types';
3 | import { Tabs } from 'antd';
4 |
5 | const { TabPane } = Tabs;
6 |
7 | const generateId = (() => {
8 | let i = 0;
9 | return (prefix = '') => {
10 | i += 1;
11 | return `${prefix}${i}`;
12 | };
13 | })();
14 |
15 | export default class LoginTab extends Component {
16 | static __ANT_PRO_LOGIN_TAB = true;
17 | static contextTypes = {
18 | tabUtil: PropTypes.object,
19 | };
20 | constructor(props) {
21 | super(props);
22 | this.uniqueId = generateId('login-tab-');
23 | }
24 | componentWillMount() {
25 | if (this.context.tabUtil) {
26 | this.context.tabUtil.addTab(this.uniqueId);
27 | }
28 | }
29 | render() {
30 | return ;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Login/index.d.ts:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import Button from "antd/lib/button";
3 | export interface LoginProps {
4 | defaultActiveKey?: string;
5 | onTabChange?: (key: string) => void;
6 | style?: React.CSSProperties;
7 | onSubmit?: (error: any, values: any) => void;
8 | }
9 |
10 | export interface TabProps {
11 | key?: string;
12 | tab?: React.ReactNode;
13 | }
14 | export class Tab extends React.Component {}
15 |
16 | export interface LoginItemProps {
17 | name?: string;
18 | rules?: any[];
19 | style?: React.CSSProperties;
20 | onGetCaptcha?: () => void;
21 | }
22 |
23 | export class LoginItem extends React.Component {}
24 |
25 | export default class Login extends React.Component {
26 | static Tab: typeof Tab;
27 | static UserName: typeof LoginItem;
28 | static Password: typeof LoginItem;
29 | static Mobile: typeof LoginItem;
30 | static Captcha: typeof LoginItem;
31 | static Submit: typeof Button;
32 | }
33 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Login/index.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | .login {
4 |
5 | .tabs {
6 | padding: 0 2px;
7 | margin: 0 -2px;
8 | :global {
9 | .ant-tabs-tab {
10 | font-size: 16px;
11 | line-height: 24px;
12 | }
13 | .ant-input-affix-wrapper .ant-input:not(:first-child) {
14 | padding-left: 34px;
15 | }
16 | }
17 | }
18 |
19 | :global {
20 | .ant-tabs .ant-tabs-bar {
21 | border-bottom: 0;
22 | margin-bottom: 24px;
23 | text-align: center;
24 | }
25 |
26 | .ant-form-item {
27 | margin-bottom: 24px;
28 | }
29 | }
30 |
31 | .prefixIcon {
32 | font-size: @font-size-base;
33 | color: @disabled-color;
34 | }
35 |
36 | .getCaptcha {
37 | display: block;
38 | width: 100%;
39 | }
40 |
41 | .submit {
42 | width: 100%;
43 | margin-top: 24px;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Login/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title:
3 | en-US: Login
4 | zh-CN: Login
5 | subtitle: 登录
6 | cols: 1
7 | order: 15
8 | ---
9 |
10 | 支持多种登录方式切换,内置了几种常见的登录控件,可以灵活组合,也支持和自定义控件配合使用。
11 |
12 | ## API
13 |
14 | ### Login
15 |
16 | 参数 | 说明 | 类型 | 默认值
17 | ----|------|-----|------
18 | defaultActiveKey | 默认激活 tab 面板的 key | String | -
19 | onTabChange | 切换页签时的回调 | (key) => void | -
20 | onSubmit | 点击提交时的回调 | (err, values) => void | -
21 |
22 | ### Login.Tab
23 |
24 | 参数 | 说明 | 类型 | 默认值
25 | ----|------|-----|------
26 | key | 对应选项卡的 key | String | -
27 | tab | 选项卡头显示文字 | ReactNode | -
28 |
29 | ### Login.UserName
30 |
31 | 参数 | 说明 | 类型 | 默认值
32 | ----|------|-----|------
33 | name | 控件标记,提交数据中同样以此为 key | String | -
34 | rules | 校验规则,同 Form getFieldDecorator(id, options) 中 [option.rules 的规则](getFieldDecorator(id, options)) | object[] | -
35 |
36 | 除上述属性以外,Login.UserName 还支持 antd.Input 的所有属性,并且自带默认的基础配置,包括 `placeholder` `size` `prefix` 等,这些基础配置均可被覆盖。
37 |
38 | ### Login.Password、Login.Mobile 同 Login.UserName
39 |
40 | ### Login.Captcha
41 |
42 | 参数 | 说明 | 类型 | 默认值
43 | ----|------|-----|------
44 | onGetCaptcha | 点击获取校验码的回调 | () => void | -
45 |
46 | 除上述属性以外,Login.Captcha 支持的属性与 Login.UserName 相同。
47 |
48 | ### Login.Submit
49 |
50 | 支持 antd.Button 的所有属性。
51 |
52 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Login/map.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Input, Icon } from 'antd';
3 | import styles from './index.less';
4 |
5 | const map = {
6 | UserName: {
7 | component: Input,
8 | props: {
9 | size: 'large',
10 | prefix: ,
11 | placeholder: 'admin',
12 | },
13 | rules: [{
14 | required: true, message: '请输入账户名!',
15 | }],
16 | },
17 | Password: {
18 | component: Input,
19 | props: {
20 | size: 'large',
21 | prefix: ,
22 | type: 'password',
23 | placeholder: '888888',
24 | },
25 | rules: [{
26 | required: true, message: '请输入密码!',
27 | }],
28 | },
29 | Mobile: {
30 | component: Input,
31 | props: {
32 | size: 'large',
33 | prefix: ,
34 | placeholder: '手机号',
35 | },
36 | rules: [{
37 | required: true, message: '请输入手机号!',
38 | }, {
39 | pattern: /^1\d{10}$/, message: '手机号格式错误!',
40 | }],
41 | },
42 | Captcha: {
43 | component: Input,
44 | props: {
45 | size: 'large',
46 | prefix: ,
47 | placeholder: '验证码',
48 | },
49 | rules: [{
50 | required: true, message: '请输入验证码!',
51 | }],
52 | },
53 | };
54 |
55 | export default map;
56 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/NoticeIcon/NoticeList.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Avatar, List } from 'antd';
3 | import classNames from 'classnames';
4 | import styles from './NoticeList.less';
5 |
6 | export default function NoticeList({
7 | data = [], onClick, onClear, title, locale, emptyText, emptyImage,
8 | }) {
9 | if (data.length === 0) {
10 | return (
11 |
12 | {emptyImage ? (
13 |

14 | ) : null}
15 |
{emptyText || locale.emptyText}
16 |
17 | );
18 | }
19 | return (
20 |
21 |
22 | {data.map((item, i) => {
23 | const itemCls = classNames(styles.item, {
24 | [styles.read]: item.read,
25 | });
26 | return (
27 | onClick(item)}>
28 | : null}
31 | title={
32 |
33 | {item.title}
34 |
{item.extra}
35 |
36 | }
37 | description={
38 |
39 |
40 | {item.description}
41 |
42 |
{item.datetime}
43 |
44 | }
45 | />
46 |
47 | );
48 | })}
49 |
50 |
51 | {locale.clear}{title}
52 |
53 |
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/NoticeIcon/NoticeList.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | .list {
4 | max-height: 400px;
5 | overflow: auto;
6 | .item {
7 | transition: all .3s;
8 | overflow: hidden;
9 | cursor: pointer;
10 | padding-left: 24px;
11 | padding-right: 24px;
12 |
13 | .meta {
14 | width: 100%;
15 | }
16 |
17 | .avatar {
18 | background: #fff;
19 | margin-top: 4px;
20 | }
21 |
22 | &.read {
23 | opacity: .4;
24 | }
25 | &:last-child {
26 | border-bottom: 0;
27 | }
28 | &:hover {
29 | background: @primary-1;
30 | }
31 | .title {
32 | font-weight: normal;
33 | margin-bottom: 8px;
34 | }
35 | .description {
36 | font-size: 12px;
37 | line-height: @line-height-base;
38 | }
39 | .datetime {
40 | font-size: 12px;
41 | margin-top: 4px;
42 | line-height: @line-height-base;
43 | }
44 | .extra {
45 | float: right;
46 | color: @text-color-secondary;
47 | font-weight: normal;
48 | margin-right: 0;
49 | margin-top: -1.5px;
50 | }
51 | }
52 | }
53 |
54 | .notFound {
55 | text-align: center;
56 | padding: 73px 0 88px 0;
57 | color: @text-color-secondary;
58 | img {
59 | display: inline-block;
60 | margin-bottom: 16px;
61 | height: 76px;
62 | }
63 | }
64 |
65 | .clear {
66 | height: 46px;
67 | line-height: 46px;
68 | text-align: center;
69 | color: @text-color;
70 | border-radius: 0 0 @border-radius-base @border-radius-base;
71 | border-top: 1px solid @border-color-split;
72 | transition: all .3s;
73 | cursor: pointer;
74 |
75 | &:hover {
76 | color: @heading-color;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/NoticeIcon/index.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | .popover {
4 | width: 336px;
5 | :global(.ant-popover-inner-content) {
6 | padding: 0;
7 | }
8 | }
9 |
10 | .noticeButton {
11 | cursor: pointer;
12 | display: inline-block;
13 | transition: all .3s;
14 | }
15 |
16 | .icon {
17 | font-size: 16px;
18 | padding: 4px;
19 | }
20 |
21 | .tabs {
22 | :global {
23 | .ant-tabs-nav-scroll {
24 | text-align: center;
25 | }
26 | .ant-tabs-bar {
27 | margin-bottom: 4px;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Result/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classNames from 'classnames';
3 | import { Icon } from 'antd';
4 | import styles from './index.less';
5 |
6 | export default function Result({
7 | className, type, title, description, extra, actions, ...restProps
8 | }) {
9 | const iconMap = {
10 | error: ,
11 | success: ,
12 | };
13 | const clsString = classNames(styles.result, className);
14 | return (
15 |
16 |
{iconMap[type]}
17 |
{title}
18 | {description &&
{description}
}
19 | {extra &&
{extra}
}
20 | {actions &&
{actions}
}
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/Result/index.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | .result {
4 | text-align: center;
5 | width: 72%;
6 | margin: 0 auto;
7 |
8 | .icon {
9 | font-size: 72px;
10 | line-height: 72px;
11 | margin-bottom: 24px;
12 |
13 | & > .success {
14 | color: @success-color;
15 | }
16 |
17 | & > .error {
18 | color: @error-color;
19 | }
20 | }
21 |
22 | .title {
23 | font-size: 24px;
24 | color: @heading-color;
25 | font-weight: 500;
26 | line-height: 32px;
27 | margin-bottom: 16px;
28 | }
29 |
30 | .description {
31 | font-size: 14px;
32 | line-height: 22px;
33 | color: @text-color-secondary;
34 | margin-bottom: 24px;
35 | }
36 |
37 | .extra {
38 | background: #fafafa;
39 | padding: 24px 40px;
40 | border-radius: @border-radius-sm;
41 | text-align: left;
42 | }
43 |
44 | .actions {
45 | margin-top: 32px;
46 |
47 | button:not(:last-child) {
48 | margin-right: 8px;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/SiderMenu/index.js:
--------------------------------------------------------------------------------
1 | import 'rc-drawer-menu/assets/index.css';
2 | import React from 'react';
3 | import DrawerMenu from 'rc-drawer-menu';
4 | import SiderMenu from './SiderMenu';
5 |
6 | export default props => (
7 | props.isMobile ? (
8 | { props.onCollapse(true); }}
14 | width="256px"
15 | >
16 |
17 |
18 | ) :
19 | );
20 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/components/SiderMenu/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 | padding-left: (@menu-collapsed-width - 32px) / 2;
8 | transition: all .3s;
9 | background: #002140;
10 | overflow: hidden;
11 | img {
12 | display: inline-block;
13 | vertical-align: middle;
14 | height: 32px;
15 | }
16 | h1 {
17 | color: #fff;
18 | display: inline-block;
19 | vertical-align: middle;
20 | font-size: 20px;
21 | margin: 0 0 0 12px;
22 | font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
23 | font-weight: 600;
24 | }
25 | }
26 |
27 | .sider {
28 | min-height: 100vh;
29 | box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
30 | position: relative;
31 | z-index: 10;
32 | }
33 |
34 | .icon {
35 | width: 14px;
36 | margin-right: 10px;
37 | }
38 |
39 | :global {
40 | .drawer .drawer-content {
41 | background: #001529;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/e2e/home.e2e.js:
--------------------------------------------------------------------------------
1 | import Nightmare from 'nightmare';
2 |
3 | describe('Homepage', () => {
4 | it('it should have logo text', async () => {
5 | const page = Nightmare().goto('http://localhost:8000');
6 | const text = await page.wait('h1').evaluate(() => document.body.innerHTML).end();
7 | expect(text).toContain('Ant Design Pro
');
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/e2e/login.e2e.js:
--------------------------------------------------------------------------------
1 | import Nightmare from 'nightmare';
2 |
3 | describe('Login', () => {
4 | let page;
5 | beforeEach(() => {
6 | page = Nightmare();
7 | page
8 | .goto('http://localhost:8000/')
9 | .evaluate(() => {
10 | window.localStorage.setItem('antd-pro-authority', 'guest');
11 | })
12 | .goto('http://localhost:8000/#/user/login');
13 | });
14 |
15 | it('should login with failure', async () => {
16 | await page.type('#userName', 'mockuser')
17 | .type('#password', 'wrong_password')
18 | .click('button[type="submit"]')
19 | .wait('.ant-alert-error') // should display error
20 | .end();
21 | });
22 |
23 | it('should login successfully', async () => {
24 | const text = await page.type('#userName', 'admin')
25 | .type('#password', '888888')
26 | .click('button[type="submit"]')
27 | .wait('.ant-layout-sider h1') // should display error
28 | .evaluate(() => document.body.innerHTML)
29 | .end();
30 | expect(text).toContain('Ant Design Pro
');
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Ant Design Pro
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/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/base-antd-pro/src/index.less:
--------------------------------------------------------------------------------
1 | html,
2 | body,
3 | :global(#root) {
4 | height: 100%;
5 | }
6 |
7 |
8 | :global(.ant-layout) {
9 | min-height: 100%;
10 | }
11 |
12 | canvas {
13 | display: block;
14 | }
15 |
16 | body {
17 | text-rendering: optimizeLegibility;
18 | -webkit-font-smoothing: antialiased;
19 | -moz-osx-font-smoothing: grayscale;
20 | }
21 |
22 | .globalSpin {
23 | width: 100%;
24 | margin: 40px 0 !important;
25 | }
26 |
27 | // temp fix for https://github.com/ant-design/ant-design/commit/a1fafb5b727b62cb0be29ce6e9eca8f579d4f8b7
28 | :global {
29 | .ant-spin-container {
30 | overflow: visible !important;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/layouts/PageHeaderLayout.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'dva/router';
3 | import PageHeader from '../components/PageHeader';
4 | import styles from './PageHeaderLayout.less';
5 |
6 | export default ({ children, wrapperClassName, top, ...restProps }) => (
7 |
8 | {top}
9 |
10 | {children ?
{children}
: null}
11 |
12 | );
13 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/layouts/PageHeaderLayout.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | .content {
4 | margin: 24px 24px 0;
5 | }
6 |
7 | @media screen and (max-width: @screen-sm) {
8 | .content {
9 | margin: 24px 0 0;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/layouts/UserLayout.less:
--------------------------------------------------------------------------------
1 | @import "~antd/lib/style/themes/default.less";
2 |
3 | .container {
4 | display: flex;
5 | flex-direction: column;
6 | min-height: 100%;
7 | background: #f0f2f5;
8 | }
9 |
10 | .content {
11 | padding: 32px 0;
12 | flex: 1;
13 | }
14 |
15 | @media (min-width: @screen-md-min) {
16 | .container {
17 | background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg');
18 | background-repeat: no-repeat;
19 | background-position: center 110px;
20 | background-size: 100%;
21 | }
22 |
23 | .content {
24 | padding: 112px 0 24px 0;
25 | }
26 | }
27 |
28 | .top {
29 | text-align: center;
30 | }
31 |
32 | .header {
33 | height: 44px;
34 | line-height: 44px;
35 | a {
36 | text-decoration: none;
37 | }
38 | }
39 |
40 | .logo {
41 | height: 44px;
42 | vertical-align: top;
43 | margin-right: 16px;
44 | }
45 |
46 | .title {
47 | font-size: 33px;
48 | color: @heading-color;
49 | font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
50 | font-weight: 600;
51 | position: relative;
52 | top: 2px;
53 | }
54 |
55 | .desc {
56 | font-size: @font-size-base;
57 | color: @text-color-secondary;
58 | margin-top: 12px;
59 | margin-bottom: 40px;
60 | }
61 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/models/error.js:
--------------------------------------------------------------------------------
1 | import { query403, query401, query404, query500 } from '../services/error';
2 |
3 | export default {
4 | namespace: 'error',
5 |
6 | state: {
7 | error: '',
8 | isloading: false,
9 | },
10 |
11 | effects: {
12 | *query403(_, { call, put }) {
13 | yield call(query403);
14 | yield put({
15 | type: 'trigger',
16 | payload: '403',
17 | });
18 | },
19 | *query401(_, { call, put }) {
20 | yield call(query401);
21 | yield put({
22 | type: 'trigger',
23 | payload: '401',
24 | });
25 | },
26 | *query500(_, { call, put }) {
27 | yield call(query500);
28 | yield put({
29 | type: 'trigger',
30 | payload: '500',
31 | });
32 | },
33 | *query404(_, { call, put }) {
34 | yield call(query404);
35 | yield put({
36 | type: 'trigger',
37 | payload: '404',
38 | });
39 | },
40 | },
41 |
42 | reducers: {
43 | trigger(state, action) {
44 | return {
45 | error: action.payload,
46 | };
47 | },
48 | },
49 | };
50 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/models/global.js:
--------------------------------------------------------------------------------
1 | import { queryNotices } from '../services/api';
2 |
3 | export default {
4 | namespace: 'global',
5 |
6 | state: {
7 | collapsed: false,
8 | notices: [],
9 | },
10 |
11 | effects: {
12 | *fetchNotices(_, { call, put }) {
13 | const data = yield call(queryNotices);
14 | yield put({
15 | type: 'saveNotices',
16 | payload: data,
17 | });
18 | yield put({
19 | type: 'user/changeNotifyCount',
20 | payload: data.length,
21 | });
22 | },
23 | *clearNotices({ payload }, { put, select }) {
24 | yield put({
25 | type: 'saveClearedNotices',
26 | payload,
27 | });
28 | const count = yield select(state => state.global.notices.length);
29 | yield put({
30 | type: 'user/changeNotifyCount',
31 | payload: count,
32 | });
33 | },
34 | },
35 |
36 | reducers: {
37 | changeLayoutCollapsed(state, { payload }) {
38 | return {
39 | ...state,
40 | collapsed: payload,
41 | };
42 | },
43 | saveNotices(state, { payload }) {
44 | return {
45 | ...state,
46 | notices: payload,
47 | };
48 | },
49 | saveClearedNotices(state, { payload }) {
50 | return {
51 | ...state,
52 | notices: state.notices.filter(item => item.type !== payload),
53 | };
54 | },
55 | },
56 |
57 | subscriptions: {
58 | setup({ history }) {
59 | // Subscribe history(url) change, trigger `load` action if pathname is `/`
60 | return history.listen(({ pathname, search }) => {
61 | if (typeof window.ga !== 'undefined') {
62 | window.ga('send', 'pageview', pathname + search);
63 | }
64 | });
65 | },
66 | },
67 | };
68 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/models/login.js:
--------------------------------------------------------------------------------
1 | import { routerRedux } from 'dva/router';
2 | import { fakeAccountLogin } from '../services/api';
3 | import { setAuthority } from '../utils/authority';
4 | import { reloadAuthorized } from '../utils/Authorized';
5 |
6 | export default {
7 | namespace: 'login',
8 |
9 | state: {
10 | status: undefined,
11 | },
12 |
13 | effects: {
14 | *login({ payload }, { call, put }) {
15 | const response = yield call(fakeAccountLogin, payload);
16 | yield put({
17 | type: 'changeLoginStatus',
18 | payload: response,
19 | });
20 | // Login successfully
21 | if (response.status === 'ok') {
22 | reloadAuthorized();
23 | yield put(routerRedux.push('/'));
24 | }
25 | },
26 | *logout(_, { put, select }) {
27 | try {
28 | // get location pathname
29 | const urlParams = new URL(window.location.href);
30 | const pathname = yield select(state => state.routing.location.pathname);
31 | // add the parameters in the url
32 | urlParams.searchParams.set('redirect', pathname);
33 | window.history.replaceState(null, 'login', urlParams.href);
34 | } finally {
35 | yield put({
36 | type: 'changeLoginStatus',
37 | payload: {
38 | status: false,
39 | currentAuthority: 'guest',
40 | },
41 | });
42 | reloadAuthorized();
43 | yield put(routerRedux.push('/user/login'));
44 | }
45 | },
46 | },
47 |
48 | reducers: {
49 | changeLoginStatus(state, { payload }) {
50 | setAuthority(payload.currentAuthority);
51 | return {
52 | ...state,
53 | status: payload.status,
54 | type: payload.type,
55 | };
56 | },
57 | },
58 | };
59 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/models/register.js:
--------------------------------------------------------------------------------
1 | import { fakeRegister } from '../services/api';
2 | import { setAuthority } from '../utils/authority';
3 | import { reloadAuthorized } from '../utils/Authorized';
4 |
5 | export default {
6 | namespace: 'register',
7 |
8 | state: {
9 | status: undefined,
10 | },
11 |
12 | effects: {
13 | *submit(_, { call, put }) {
14 | const response = yield call(fakeRegister);
15 | yield put({
16 | type: 'registerHandle',
17 | payload: response,
18 | });
19 | },
20 | },
21 |
22 | reducers: {
23 | registerHandle(state, { payload }) {
24 | setAuthority('user');
25 | reloadAuthorized();
26 | return {
27 | ...state,
28 | status: payload.status,
29 | };
30 | },
31 | },
32 | };
33 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/models/user.js:
--------------------------------------------------------------------------------
1 | import { query as queryUsers, queryCurrent } from '../services/user';
2 |
3 | export default {
4 | namespace: 'user',
5 |
6 | state: {
7 | list: [],
8 | currentUser: {},
9 | },
10 |
11 | effects: {
12 | *fetch(_, { call, put }) {
13 | const response = yield call(queryUsers);
14 | yield put({
15 | type: 'save',
16 | payload: response,
17 | });
18 | },
19 | *fetchCurrent(_, { call, put }) {
20 | const response = yield call(queryCurrent);
21 | yield put({
22 | type: 'saveCurrentUser',
23 | payload: response,
24 | });
25 | },
26 | },
27 |
28 | reducers: {
29 | save(state, action) {
30 | return {
31 | ...state,
32 | list: action.payload,
33 | };
34 | },
35 | saveCurrentUser(state, action) {
36 | return {
37 | ...state,
38 | currentUser: {
39 | name: 'Serati Ma',
40 | avatar: 'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png',
41 | userid: '00000001',
42 | notifyCount: 12,
43 | },
44 | };
45 | },
46 | changeNotifyCount(state, action) {
47 | return {
48 | ...state,
49 | currentUser: {
50 | ...state.currentUser,
51 | notifyCount: action.payload,
52 | },
53 | };
54 | },
55 | },
56 | };
57 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/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/base-antd-pro/src/routes/Exception/403.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/base-antd-pro/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/base-antd-pro/src/routes/Exception/500.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/base-antd-pro/src/routes/Exception/style.less:
--------------------------------------------------------------------------------
1 | .trigger {
2 | background: "red";
3 | :global(.ant-btn) {
4 | margin-right: 8px;
5 | margin-bottom: 12px;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/cli/base-antd-pro/src/routes/Exception/triggerException.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react';
2 | import { Button, Spin, Card } from 'antd';
3 | import { connect } from 'dva';
4 | import styles from './style.less';
5 |
6 | @connect(state => ({
7 | isloading: state.error.isloading,
8 | }))
9 | export default class TriggerException extends PureComponent {
10 | state={
11 | isloading: false,
12 | }
13 | trigger401 = () => {
14 | this.setState({
15 | isloading: true,
16 | });
17 | this.props.dispatch({
18 | type: 'error/query401',
19 | });
20 | };
21 | trigger403 = () => {
22 | this.setState({
23 | isloading: true,
24 | });
25 | this.props.dispatch({
26 | type: 'error/query403',
27 | });
28 | };
29 | trigger500 = () => {
30 | this.setState({
31 | isloading: true,
32 | });
33 | this.props.dispatch({
34 | type: 'error/query500',
35 | });
36 | };
37 | trigger404 = () => {
38 | this.setState({
39 | isloading: true,
40 | });
41 | this.props.dispatch({
42 | type: 'error/query404',
43 | });
44 | };
45 | render() {
46 | return (
47 |
48 |
49 |
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 |
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 |
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 |
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 |
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 |

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 |
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 |
51 |
52 |
53 |
54 |
57 |
58 |
59 | )
60 | }
61 | }
62 |
63 | export default CommentInput
--------------------------------------------------------------------------------
/middle-demo/comment-app/src/CommentList.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Comment from './Comment'
3 |
4 | class CommentList extends Component {
5 | static defaultProps = {
6 | comments: []
7 | }
8 |
9 | render() {
10 | return (
11 |
12 | {this.props.comments.map((comment, i) =>
13 |
14 | )}
15 |
16 | )
17 | }
18 | }
19 |
20 | export default CommentList
--------------------------------------------------------------------------------
/middle-demo/comment-app/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | background-color: #fbfbfb;
6 | width: 50%;
7 | margin: auto;
8 | }
9 |
10 | .wrapper {
11 | width: 500px;
12 | margin: 10px auto;
13 | font-size: 14px;
14 | background-color: #fff;
15 | border: 1px solid #f1f1f1;
16 | padding: 20px;
17 | }
18 |
19 | /* 评论框样式 */
20 | .comment-input {
21 | background-color: #fff;
22 | border: 1px solid #f1f1f1;
23 | padding: 20px;
24 | margin-bottom: 10px;
25 | }
26 |
27 | .comment-field {
28 | margin-bottom: 15px;
29 | display: flex;
30 | }
31 |
32 | .comment-field .comment-field-name {
33 | display: flex;
34 | flex-basis: 100px;
35 | font-size: 14px;
36 | }
37 |
38 | .comment-field .comment-field-input {
39 | display: flex;
40 | flex: 1;
41 | }
42 |
43 | .comment-field-input input,
44 | .comment-field-input textarea {
45 | border: 1px solid #e6e6e6;
46 | border-radius: 3px;
47 | padding: 5px;
48 | outline: none;
49 | font-size: 14px;
50 | resize: none;
51 | flex: 1;
52 | }
53 |
54 | .comment-field-input textarea {
55 | height: 100px;
56 | }
57 |
58 | .comment-field-button {
59 | display: flex;
60 | justify-content: flex-end;
61 | }
62 |
63 | .comment-field-button button {
64 | padding: 5px 10px;
65 | width: 80px;
66 | border: none;
67 | border-radius: 3px;
68 | background-color: #00a3cf;
69 | color: #fff;
70 | outline: none;
71 | cursor: pointer;
72 | }
73 |
74 | .comment-field-button button:active {
75 | background: #13c1f1;
76 | }
77 |
78 | /* 评论列表样式 */
79 | .comment-list {
80 | background-color: #fff;
81 | border: 1px solid #f1f1f1;
82 | padding: 20px;
83 | }
84 |
85 | /* 评论组件样式 */
86 | .comment {
87 | /* display: flex; */
88 | border-bottom: 1px solid #f1f1f1;
89 | margin-bottom: 10px;
90 | padding-bottom: 10px;
91 | min-height: 50px;
92 | }
93 |
94 | .comment .comment-user {
95 | flex-shrink: 0;
96 | }
97 |
98 | .comment span {
99 | color: #00a3cf;
100 | font-style: italic;
101 | }
102 |
103 | .comment p {
104 | margin: 0;
105 | /*text-indent: 2em;*/
106 | }
107 |
108 |
--------------------------------------------------------------------------------
/middle-demo/comment-app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 | registerServiceWorker();
9 |
--------------------------------------------------------------------------------
/middle-demo/react表单详解/1、不可控组件实例.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 表单详解
6 |
7 |
8 |
9 |
10 |
11 |
12 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/middle-demo/react表单详解/2、可控组件实例.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 表单详解
6 |
7 |
8 |
9 |
10 |
11 |
12 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/middle-demo/react表单详解/4、bind复用.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 表单详解
6 |
7 |
8 |
9 |
10 |
11 |
12 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/middle-demo/react表单详解/5、name复用.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 表单详解
6 |
7 |
8 |
9 |
10 |
11 |
12 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/primer-demo/README.md:
--------------------------------------------------------------------------------
1 | # primer-demo
2 |
3 | 初级demo合集
4 |
5 | ## 目录讲解
6 |
7 | - React教程 : 整理自菜鸟教程,代码有过改动,代码里有知识点详解,没有复杂的语法。
--------------------------------------------------------------------------------
/primer-demo/React教程/1.React 第一个实例/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
19 |
20 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-1:多html嵌套.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-2.js:
--------------------------------------------------------------------------------
1 | ReactDOM.render(
2 | i come from jsx-2.js
,
3 | document.getElementById('example')
4 | );
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-2:jsx独立文件.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-3:使用JavaScript表达式.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-4:css样式.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-4
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-5:注释.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-5
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
30 |
31 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-6:数组.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-6
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-7:渲染html标签.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-7
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/primer-demo/React教程/2.React JSX/jsx-8:react组件初窥.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jsx-8
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
31 |
32 |
--------------------------------------------------------------------------------
/primer-demo/React教程/3.react 组件/component-1:第一个组件.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | component-1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/primer-demo/React教程/3.react 组件/component-2:向组件传递参数.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | component-2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/primer-demo/React教程/3.react 组件/component-3:复合组件.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | component-3
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
50 |
51 |
--------------------------------------------------------------------------------
/primer-demo/React教程/4.react State/state-1:第一个实例.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/primer-demo/React教程/5.React Props/props-1:使用 Props .html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | props-1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/primer-demo/React教程/5.React Props/props-2:默认props.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | props-2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/primer-demo/React教程/5.React Props/props-3:组合使用 state 和 props.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | props-3
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/primer-demo/React教程/README.md:
--------------------------------------------------------------------------------
1 | # react教程
2 |
3 | 来源于 [菜鸟教程](http://www.runoob.com/react)
4 |
5 | 部分代码有过改动。
6 |
7 | 代码中有代码讲解及知识讲解。
--------------------------------------------------------------------------------
/primer-demo/react 编程思想/1.一个简单的html.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | thinking in react
8 |
9 |
10 |
11 |
too simple html
12 |
13 |
14 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/1.传统写法.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 关注
8 |
9 |
10 |
14 |
15 |
16 |
29 |
30 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/2.结构复用.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 关注
8 |
9 |
10 |
11 |
29 |
30 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/3.简单的组件化.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 关注
8 |
9 |
10 |
11 |
52 |
53 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/4.状态改变自动更新.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 关注
8 |
9 |
10 |
11 |
61 |
62 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/5.抽象公共组件类.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 关注
8 |
9 |
10 |
11 |
71 |
72 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/6.添加 props.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 关注
8 |
9 |
10 |
11 |
71 |
72 |
--------------------------------------------------------------------------------
/primer-demo/reactjs 来源/README.md:
--------------------------------------------------------------------------------
1 | ## 来自 reactjs 小书
--------------------------------------------------------------------------------