react+ant.design——后台管理系统
程序员文章站
2024-01-04 08:25:22
...
https://react.docschina.org/docs/create-a-new-react-app.html
安装react 脚手架
npx create-react-app damon-cms-react
cd damon-cms-react
npm start
ant.design
安装antd
yarn add antd react-app-rewired customize-cra babel-plugin-import less less-loader
修改package.josn
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
}
根目录config-overrides.js 创建文件配置如下
const { override, fixBabelImports, addLessLoader } = require('customize-cra');
module.exports = override(
//写了下面这个部分,就实现了按需加载,再也不需要再每个页面里面都引入“antd/dist/antd.css”啦
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true //这里一定要写true,css和less都不行哦
}),
addLessLoader({
javascriptEnabled: true,
//下面这行很特殊,这里是更改主题的关键,这里我只更改了主色,当然还可以更改其他的,下面会详细写出。
modifyVars: { "@primary-color": "#f47983"}
})
)
初始化工程目录
public
favicon.ico ------ 浏览器头部logo
index.html ------ 项目首页模板
manifest.json ------ PWA serviceWoker 网页用户访问存储到手机的参数配置 在后台管理项目中没有作用
api
home.json ------ 测试数据
src
index.js ------ 程序入口文件
pages ------ 各个展示页面
home
store ------ 存储单独页面数据
actionCreators.js
constants.js
index.js
reducer.js
index.js ------ home页面
store
index.js ------ redux 入口文件
reducer.js ------ 改变state函数
node_modules ------ 依赖第三方包文件
.gitignore ------ git 忽略文件
package.json ------ node包文件
README.md
yarn.lock ------ 项目依赖安装包版本号
安装 redux 和 react-redux 和 redux-thunk 和 axios 和 immutable 和 redux-immutable
npm install --save redux
npm install --save react-redux
npm install --save redux-thunk
npm install --save axios
npm install --save immutable
npm install --save redux-immutable
使用 redux
public>api>home.json 文件内容
{
"success": true,
"data": {
"topicList": [{
"id": 1,
"title": "社会热点",
"imgUrl": "//upload.jianshu.io/collections/images/261938/man-hands-reading-boy-large.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64"
}, {
"id": 2,
"title": "手手绘",
"imgUrl": "//upload.jianshu.io/collections/images/21/20120316041115481.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64"
}],
"articleList": [{
"id": 1,
"title": "胡歌12年后首谈车祸",
"desc": "文/麦大人 01 胡歌又刷屏了。 近日他上了《朗读者》,而这一期的主题是“生命”,他用磁性的嗓音,朗读了一段《哈姆雷特》中的经典独白,相当震撼:...",
"imgUrl": "//upload-images.jianshu.io/upload_images/15631385-387601b6c91b14f7?imageMogr2/auto-orient/strip|imageView2/1/w/360/h/240"
} ]
}
}
src>store>index.js 文件内容
import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers(
applyMiddleware(thunk)
));
export default store;
src>store>reducer.js 文件内容
import { combineReducers } from 'redux-immutable'
import {reducer as homeReducer } from '../pages/home/store/'
export default combineReducers({
home:homeReducer,
})
home>index.js 文件内容
import React from 'react';
import { connect } from 'react-redux';
import { actionCreators } from './store';
class Home extends React.Component {
render() {
const { topicList } = this.props
return (
<div>
{
topicList.map((item, index) => {
return (
<div key={index} to={'/detail/' + item.get('id')}>
<div >
<img alt='' className='pic' src={item.get('imgUrl')} />
<div>
<h3 className='title'>{item.get('title')}</h3>
<p className='desc'>{item.get('desc')}</p>
</div>
</div>
</div>
);
})
}
</div>
)
}
componentDidMount() {
this.props.changeHomeData();
}
}
const mapState = (state) => ({
topicList: state.getIn(['home', 'topicList']),
})
const mapDispatch = (dispatch) => ({
changeHomeData() {
dispatch(actionCreators.getHomeInfo());
},
});
export default connect(mapState, mapDispatch)(Home);
src>App.js
import React from 'react';
import store from './store';
import { Provider } from 'react-redux';
import Home from './pages/home'
function App() {
return (
<Provider store={store}>
<div className="App">
<Home></Home>
</div>
</Provider>
);
}
export default App;
src>pages>home>store>actionCreators.js
import axios from 'axios';
import * as constants from './constants';
import { fromJS } from 'immutable';
const changHomeData = (result) => ({
type: constants.CHANGE_HOME_DATA,
topicList: result.topicList,
articleList: result.articleList,
recommendList: result.recommendList
});
const addHomeList = (list, nextPage) => ({
type: constants.ADD_ARTICLE_LIST,
list: fromJS(list),
nextPage
})
export const getHomeInfo = () => {
return (dispatch) => {
axios.get('/api/home.json').then((res) => {
const result = res.data.data;
dispatch(changHomeData(result));
});
}
}
export const getMoreList = (page) => {
return (dispatch) => {
axios.get('/api/homeList.json?page=' + page).then((res) => {
const result = res.data.data;
dispatch(addHomeList(result, page + 1));
});
}
}
src>pages>home>store>constants.js
export const CHANGE_HOME_DATA = 'home/CHANGE_HOME_DATA';
export const ADD_ARTICLE_LIST = 'home/ADD_ARTICLE_LIST';
src>pages>home>store>index.js
import reducer from './reducer';
import * as actionCreators from './actionCreators';
import * as constants from './constants';
export { reducer, actionCreators, constants };
src>pages>home>store>reducer.js
import { fromJS } from 'immutable';
import * as constants from './constants';
const defaultState = fromJS({
topicList: [],
articleList: [],
articlePage: 1,
});
const changeHomeData = (state, action) => {
return state.merge({
topicList: fromJS(action.topicList),
articleList: fromJS(action.articleList),
recommendList: fromJS(action.recommendList)
});
};
const addArticleList = (state, action) => {
return state.merge({
'articleList': state.get('articleList').concat(action.list),
'articlePage': action.nextPage
});
};
export default (state = defaultState, action) => {
switch(action.type) {
case constants.CHANGE_HOME_DATA:
return changeHomeData(state, action);
case constants.ADD_ARTICLE_LIST:
return addArticleList(state, action);
default:
return state;
}
}