├── .babelrc
├── .gitignore
├── README.md
├── config
├── env.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── paths.js
├── polyfills.js
├── webpack.config.dev.js
├── webpack.config.prod.js
└── webpackDevServer.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── scripts
├── build.js
├── start.js
└── test.js
├── src
├── App.css
├── App.js
├── App.test.js
├── assets
│ ├── font
│ │ ├── demo.css
│ │ ├── demo_fontclass.html
│ │ ├── demo_symbol.html
│ │ ├── demo_unicode.html
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.js
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ └── img
│ │ └── defaultUser.jpg
├── components
│ ├── ContentMain
│ │ └── index.js
│ ├── CustomBreadcrumb
│ │ └── index.js
│ ├── CustomMenu
│ │ └── index.js
│ ├── HeaderBar
│ │ ├── img
│ │ │ ├── 01.jpg
│ │ │ ├── 02.jpg
│ │ │ ├── 03.jpg
│ │ │ └── 04.jpg
│ │ └── index.js
│ ├── Loading
│ │ ├── index.js
│ │ └── style.css
│ ├── Loading2
│ │ ├── data.json
│ │ └── index.js
│ ├── PrivateRoute
│ │ └── index.js
│ ├── PromptBox
│ │ └── index.js
│ ├── SiderNav
│ │ └── index.js
│ └── TypingCard
│ │ └── index.js
├── index.css
├── index.js
├── logo.svg
├── registerServiceWorker.js
├── routes
│ ├── About
│ │ └── index.js
│ ├── Display
│ │ ├── CarouselDemo
│ │ │ ├── css
│ │ │ │ └── style.css
│ │ │ └── index.js
│ │ ├── CollapseDemo
│ │ │ └── index.js
│ │ ├── ListDemo
│ │ │ └── index.js
│ │ ├── TableDemo
│ │ │ └── index.js
│ │ └── TabsDemo
│ │ │ └── index.js
│ ├── Entry
│ │ ├── FormDemo
│ │ │ ├── FormDemo1.js
│ │ │ ├── FormDemo2.js
│ │ │ ├── css
│ │ │ │ └── formDeni2.css
│ │ │ └── store.js
│ │ └── UploadDemo
│ │ │ └── index.js
│ ├── Feedback
│ │ ├── ModalDemo
│ │ │ └── index.js
│ │ ├── NotificationDemo
│ │ │ └── index.js
│ │ └── SpinDemo
│ │ │ └── index.js
│ ├── General
│ │ ├── ButtonDemo
│ │ │ └── index.js
│ │ └── IconDemo
│ │ │ └── index.js
│ ├── Home
│ │ ├── index.js
│ │ └── style.css
│ ├── Index
│ │ └── index.js
│ ├── Login
│ │ ├── LoginForm.js
│ │ ├── RegisterForm.js
│ │ ├── index.js
│ │ └── style.css
│ ├── Login2
│ │ ├── img
│ │ │ ├── bg2.jpg
│ │ │ ├── bg3.jpg
│ │ │ ├── bg3a.jpg
│ │ │ ├── bg4.jpg
│ │ │ ├── bg5.jpg
│ │ │ ├── owl-login-arm.png
│ │ │ ├── owl-login.png
│ │ │ └── snow.jpg
│ │ ├── index.js
│ │ └── style.css
│ ├── Navigation
│ │ ├── DropdownDemo
│ │ │ └── index.js
│ │ ├── MenuDemo
│ │ │ └── index.js
│ │ └── StepsDemo
│ │ │ └── index.js
│ └── Other
│ │ ├── AnimationDemo
│ │ └── index.js
│ │ ├── ChartDemo
│ │ └── index.js
│ │ ├── DraftDemo
│ │ ├── index.js
│ │ └── style.css
│ │ ├── ErrorPage
│ │ ├── index.js
│ │ └── style.css
│ │ ├── GalleryDemo
│ │ ├── img
│ │ │ ├── 01.jpeg
│ │ │ ├── 02.jpeg
│ │ │ ├── 03.jpeg
│ │ │ ├── 04.jpeg
│ │ │ ├── 05.jpeg
│ │ │ ├── 06.jpeg
│ │ │ ├── 07.jpeg
│ │ │ ├── 08.jpeg
│ │ │ ├── 09.jpeg
│ │ │ ├── 10.jpeg
│ │ │ ├── 11.jpeg
│ │ │ └── 12.jpeg
│ │ └── index.js
│ │ ├── LoadingDemo
│ │ └── index.js
│ │ └── SpringText
│ │ └── index.js
├── store
│ ├── appStore.js
│ └── index.js
└── utils
│ ├── AsyncComponent.js
│ ├── BGParticle.js
│ ├── LoadableComponent.js
│ ├── Session.js
│ ├── gVerify.js
│ ├── typing.js
│ └── utils.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets":["react-app"],
3 | "plugins": [
4 | ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }],
5 | ["transform-decorators-legacy"]
6 | ]
7 | }
--------------------------------------------------------------------------------
/.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 | /.idea
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 基于React+antd实现后台模板
2 | 自己利用业余时间,基于React+antd写了一个后台管理模板。主要是熟悉antd组件和React,页面主要还是展示页面,比较简单不涉及后台交互。
3 |
4 | github地址:[基于React+antd实现后台模板](https://github.com/z-9527/react-admin-master)
5 | 预览地址:服务器到期,暂时没有预览地址
6 |
7 |
8 | 项目重构地址:[react+koa实现登陆、聊天、留言板功能后台](https://github.com/z-9527/admin)
9 | 重构预览地址:服务器到期,暂时没有预览地址
10 |
11 | 2019.3.19更新
12 | 今天回顾了一下项目,发现组件写的有问题,公共组件中不应该写业务逻辑,业务逻辑应该通过props或传递事件来实现;或者再用容器组件封装。
13 | webstorm打开项目时占用内存过高,不知道是不是代码的问题。
14 | 项目的初衷是为了学习和总结,可能前期写的或多或少有些问题,但正是通过解决这些问题才能不断的提升。
15 |
16 |
17 | 2019.3.7更新
18 | 登录后浏览器后退按钮可以回到登录页,登录页不登录,通过浏览器的前进又可直接进入前台。
19 | 我在登录页componentWillMount生命周期加了判断,如果已经登录,重定向到前页面(也可以设置退出登录)
20 |
21 |
22 |
23 | ### 技术栈
24 |
25 | - react
26 | - antd
27 | - react-router
28 | - mobx
29 | - canvas
30 | - ES6
31 | - cookie
32 |
33 | 自己参考了其他优秀的插件,比如[动态打字效果](https://blog.csdn.net/qq_37860930/article/details/80859473)、背景粒子效果、[shuffle(洗牌)](https://github.com/Vestride/Shuffle),[全屏插件](https://github.com/sindresorhus/screenfull.js)等,自己对有些插件封装成类使用
34 |
35 | 所有路由都需要登录才可进入,自己封装了PrivateRoute组件来实现路由认证,登录信息保存在cookie中,原本是保存在store中,但是刷新页面后登录状态丢失,所以就保存在cookie中
36 | 登录背景图太大,使用了[TinyPNG](https://tinypng.com/)进行压缩,并编写了一个loading效果
37 |
38 |
39 | ### 项目目录结构
40 |
41 |
42 | assets----存储静态图片资源和共用icon图标
43 | components----存储共用组件
44 | routes----业务页面入口和常用模板
45 | store----状态管理
46 | utils----工具函数
47 |
48 |
49 | ### 项目截图
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | ### 问题
58 |
59 | 整个demo不复杂,主要是熟悉react和路由等,在打包的过程中出现了一点小问题。我打包的文件是放在服务器二级目录下,所以打包的路径要改为相对路径,不能使用绝对路径,我在package.json中添加了homepage:'.'解决了路径问题。然后BrowserRouter加上了 basename=‘二级目录名称’ 属性,结果还是出现js路径错误,我一直以为是webpack打包的问题,找了很久才发现是因为BrowserRouter,将BrowserRouter改为HashRouter就访问正确。
60 | 使用react-router(v4)时,如果有服务器端的动态支持,建议使用 BrowserRouter,否则建议使用 HashRouter。
61 | BrowserRouter和HashRouter其实就是前端路由的两种实现方式,一种是hash和一种是HTML5的history,网上有很介绍。
62 | 可以参考:[关于react 在打包后:“找不到资源路径”的问题、部署到服务器二级目录 “打开为空白” 的问题](https://blog.csdn.net/Sophie_U/article/details/80006723)
63 |
64 |
65 | ### 最后
66 | demo是我断断续续写的,只有下班和周末有时间。写demo的目的主要是熟悉React和react-router以及antd,整个demo中参考了一些其他人的想法,如动画效果等。另外基于vue的个人项目可以看这个[仿制移动端QQ音乐](https://blog.csdn.net/qq_37860930/article/details/80586698)
67 |
68 |
69 | ### 其他个人项目
70 |
71 | - [基于vue+vue-router+jsonp+vuex仿制的移动端`QQ音乐`](https://github.com/zhangZhiHao1996/vue-music-master)
72 | - [基于React-Antd的`后台模板Demo`](https://github.com/zhangZhiHao1996/react-admin-master)
73 | - [基于原生小程序精仿的`猫眼电影小程序`](https://github.com/zhangZhiHao1996/weapp-movie-master)
74 |
75 |
76 |
77 | `觉得不错的给个star鼓励支持!^_^`
78 |
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const paths = require('./paths');
6 |
7 | // Make sure that including paths.js after env.js will read .env variables.
8 | delete require.cache[require.resolve('./paths')];
9 |
10 | const NODE_ENV = process.env.NODE_ENV;
11 | if (!NODE_ENV) {
12 | throw new Error(
13 | 'The NODE_ENV environment variable is required but was not specified.'
14 | );
15 | }
16 |
17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
18 | var dotenvFiles = [
19 | `${paths.dotenv}.${NODE_ENV}.local`,
20 | `${paths.dotenv}.${NODE_ENV}`,
21 | // Don't include `.env.local` for `test` environment
22 | // since normally you expect tests to produce the same
23 | // results for everyone
24 | NODE_ENV !== 'test' && `${paths.dotenv}.local`,
25 | paths.dotenv,
26 | ].filter(Boolean);
27 |
28 | // Load environment variables from .env* files. Suppress warnings using silent
29 | // if this file is missing. dotenv will never modify any environment variables
30 | // that have already been set. Variable expansion is supported in .env files.
31 | // https://github.com/motdotla/dotenv
32 | // https://github.com/motdotla/dotenv-expand
33 | dotenvFiles.forEach(dotenvFile => {
34 | if (fs.existsSync(dotenvFile)) {
35 | require('dotenv-expand')(
36 | require('dotenv').config({
37 | path: dotenvFile,
38 | })
39 | );
40 | }
41 | });
42 |
43 | // We support resolving modules according to `NODE_PATH`.
44 | // This lets you use absolute paths in imports inside large monorepos:
45 | // https://github.com/facebookincubator/create-react-app/issues/253.
46 | // It works similar to `NODE_PATH` in Node itself:
47 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
48 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
49 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
50 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
51 | // We also resolve them to make sure all tools using them work consistently.
52 | const appDirectory = fs.realpathSync(process.cwd());
53 | process.env.NODE_PATH = (process.env.NODE_PATH || '')
54 | .split(path.delimiter)
55 | .filter(folder => folder && !path.isAbsolute(folder))
56 | .map(folder => path.resolve(appDirectory, folder))
57 | .join(path.delimiter);
58 |
59 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
60 | // injected into the application via DefinePlugin in Webpack configuration.
61 | const REACT_APP = /^REACT_APP_/i;
62 |
63 | function getClientEnvironment(publicUrl) {
64 | const raw = Object.keys(process.env)
65 | .filter(key => REACT_APP.test(key))
66 | .reduce(
67 | (env, key) => {
68 | env[key] = process.env[key];
69 | return env;
70 | },
71 | {
72 | // Useful for determining whether we’re running in production mode.
73 | // Most importantly, it switches React into the correct mode.
74 | NODE_ENV: process.env.NODE_ENV || 'development',
75 | // Useful for resolving the correct path to static assets in `public`.
76 | // For example,
.
77 | // This should only be used as an escape hatch. Normally you would put
78 | // images into the `src` and `import` them in code to get their paths.
79 | PUBLIC_URL: publicUrl,
80 | }
81 | );
82 | // Stringify all values so we can feed into Webpack DefinePlugin
83 | const stringified = {
84 | 'process.env': Object.keys(raw).reduce((env, key) => {
85 | env[key] = JSON.stringify(raw[key]);
86 | return env;
87 | }, {}),
88 | };
89 |
90 | return { raw, stringified };
91 | }
92 |
93 | module.exports = getClientEnvironment;
94 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/en/webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(path, needsSlash) {
15 | const hasSlash = path.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return path.substr(path, path.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${path}/`;
20 | } else {
21 | return path;
22 | }
23 | }
24 |
25 | const getPublicUrl = appPackageJson =>
26 | envPublicUrl || require(appPackageJson).homepage;
27 |
28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 | // "public path" at which the app is served.
30 | // Webpack needs to know it to put the right