- react
- axios
- less
- antd4
- react-draft-wysiwyg
- draftjs-to-html
- jsonp
登入頁
首頁
商品->品類管理
商品->品類管理->更新分類
商品->品類管理->查看子分類
商品->品類管理->添加分類
商品->商品管理
商品->商品管理->詳情
商品->商品管理->修改
商品->商品管理->添加商品
商品->用戶管理
角色管理
角色管理->設置角色權限
角色管理->創建角色
npm i create-react-app -g
create-react-app react-admin
進入項目運行
cd react-admin
npm start
npm run build
npm install -g serve
serve build
刪除項目建構時的檔案
建立新的目錄結構
https://ant.design/docs/react/use-with-create-react-app-cn
安裝
npm i antd
npm i react-app-rewired customize-cra babel-plugin-import
config-overrides.js
const { override, fixBabelImports } = require('customize-cra')
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: 'css',
})
)
原配置
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
修改後配置
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
安裝依賴
npm i less less-loader
const { override, fixBabelImports,addLessLoader } = require('customize-cra')
module.exports = override(
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true,
}),
addLessLoader({
lessOptions: {
javascriptEnabled: true,
modifyVars: { '@primary-color': '#cccccc' },
},
sourceMap:true,
}),
)
推測是版本問題
先使用之前完成的項目為基底,繼續先行開發
https://github.com/IvesShe/React_AntDesign
npm install react-router-dom@5.2.0
沒指定版本的話,目前這時間安裝(2022/1/5),會裝到6版的,寫法與舊版的不同,真的蠻多坑的
npm i axios
/api/ajax.js
import axios from 'axios'
export default function ajax(url, data = {}, type = 'GET') {
if (type === 'GET') {
return axios.get(url, {
params: data
})
} else if (type === 'POST') {
return axios.post(url, data)
} else {
console.log("@@@ajax", type)
}
}
/api/index.js
import ajax from './ajax'
// 登入
export const reqLogin = (username, password) => ajax('/login', { username, password }, 'POST')
// 添加用戶
export const reqAddUser = (user) => ajax('/manage/user/add', user, 'POST')
package.json
"proxy": "http://localhost:5000"
https://github.com/marcuswestin/store.js
安裝store代替localStorage(localStorage有瀏覽器兼容問題)
npm i store
封裝緩存
memoryUtils.js
export default{
user: {},
}
封裝localStorage
storageUtils.js
import store from 'store'
const USER_KEY = 'user_key'
export default {
saveUser(user) {
//localStorage.setItem(USER_KEY, JSON.stringify(user))
store.set(USER_KEY, user)
},
getUser() {
//return JSON.parse(localStorage.getItem(USER_KEY) || '{}')
return store.get(USER_KEY) || {}
},
removeUser() {
//localStorage.removeItem(USER_KEY)
store.remove(USER_KEY)
}
}
import React, { Component } from 'react'
import { Redirect } from 'react-router-dom';
import './Login.less'
import logo from './images/logo.jpg'
import { Form, Input, Button, message } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import { reqLogin } from '../../api'
import memoryUtils from '../../utils/memoryUtils';
import storageUtils from '../../utils/storageUtils';
export default class Login extends Component {
render() {
const user = memoryUtils.user
if (user && user._id) {
return <Redirect to='/' />
}
const onFinish = async (values) => {
console.log('Received values of form: ', values)
const { username, password } = values
try {
const res = await reqLogin(username, password)
console.log("@@@reqLogin res", res.data)
const result = res.data
if (result.status === 0) {
message.success('登入成功')
const user = result.data
memoryUtils.user = user
storageUtils.saveUser = user
this.props.history.replace('/')
} else {
message.error(result.msg)
}
} catch (err) {
console.log("@@@reqLogin err", err.message)
}
}
return (
<div className='login'>
<header className='login-header'>
<img src={logo} alt="logo" />
<h1>React項目: 後台管理系統</h1>
</header>
<section className='login-content'>
<h2>用戶登入</h2>
<div>
<Form
name="normal_login"
className="login-form"
initialValues={{
remember: true,
}}
onFinish={onFinish}
>
<Form.Item
name="username"
rules={[
{
required: true,
whitespace: true,
message: '用戶名必須輸入!',
},
{
min: 4,
message: '用戶名至少4位!',
},
{
max: 12,
message: '用戶名最多12位!',
},
{
pattern: /^[a-zA-Z-0-9_]+$/,
message: '用戶名必須是英文、數字或下劃線組成!',
},
]}
>
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="用戶名" />
</Form.Item>
<Form.Item
name="password"
rules={[
({ getFieldValue }) => ({
validator(_, value) {
console.log("@@@getFieldValue", value)
if (!value) {
return Promise.reject(new Error('密碼必須輸入!'));
} else if (value.length < 4) {
return Promise.reject(new Error('密碼長度不能小於4位!'));
} else if (value.length > 12) {
return Promise.reject(new Error('密碼長度不能大於12位!'));
} else if (!/^[a-zA-Z-0-9_]+$/.test(value)) {
return Promise.reject(new Error('密碼必須是英文、數字或下劃線組成!'));
}
return Promise.resolve();
},
}),
]}
>
<Input
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder="密碼"
/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button">
登入
</Button>
</Form.Item>
</Form>
</div>
</section>
</div>
)
}
}
.login{
width: 100%;
height: 100%;
background-color: darkred;
.login-header{
display: flex;
align-items: center;
height: 80px;
background-color: rgba(21,20,13,0.5);
img{
display: block;
width: 40px;
height: 40px;
border-radius: 20px;
margin: 0 15px 0 50px;
}
h1{
font-size: 30px;
color: #fff;
line-height: 80px;
margin: 0px;
}
}
.login-content{
width: 400px;
height: 300px;
background-color: #fff;
margin: 50px auto;
padding: 20px 40px;
h2{
text-align: center;
font-size: 30px;
font-weight: bold;
margin-bottom: 20px;
}
.login-form {
.login-form-button{
width: 100%;
}
}
}
}
npm i jsonp
npm install draftjs-to-html
npm install --save react-draft-wysiwyg draft-js