# react-demo
**Repository Path**: hellozdq/react-demo
## Basic Information
- **Project Name**: react-demo
- **Description**: use webapck and react
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-08-25
- **Last Updated**: 2021-08-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## react 简易的后台页面基础架构
### 类似 vue-element-admin 的后台管理模板,包含侧边栏、头部导航标签和需要导航跳转的主要页面

### 拉取使用
1. git clone https://github.com/hellozdq/react-demo.git 拉取项目
2. yarn 安装依赖
3. yarn run dev 运行
### 结构
- src 函数式写法
- common 公共函数
- components 公共组件
- Layout 布局
- pages 页面
- router 路由
- store redux
- APP.jsx 主要组件
- src_001 测试
- src_002 测试
- src_class class 写法
### webpack + react + redux + router + antd + less
```
npm i react react-dom -S //安装react
npm i react-router-dom -D //安装router
npm i redux react-redux -D //安装redux
npm i css-loader style-loader less -D 安装less
npm i antd -S //安装 antd组件库
npm i pubsub-js -S //用于订阅和发布传参
npm i react-thunk -S //用于redux 的异步操作
```
## 记录
### class函数的三种写法
```
import React,{Component} from "react"
class Home extends Component{
constructor(props){
super(props)
this.name = 1;
this.fun2 = this.fun2.bind(this)/* 2 */
}
/* 1 */
fun = () => {
console.log(this.name)
console.log("-----------------1")
}
/* 2 */
fun2(){
console.log(this.name)
console.log("-----------------2")
}
/* 3 */
fun3(){
console.log(this.name)
console.log("-----------------3")
}
render(){
return (
{/* 1 */}
{/* 2 */}
{/* 3 */}
)
}
}
```
### 获取ref 的4种方法
```
import React,{Component} from "react"
class Home extends Component{
constructor(props){
super(props)
this.refName = React.createRef();//1
this.refName2 = null;//2
this.refName3 = null;//3
}
getRef = (e) => {
this.refName3 = e
}
componentDidMount(){
console.log(this.refName.current) //1
console.log(this.refName2)//2
console.log(this.refName3)//3
console.log(this.refs.refName) //4 已废弃
}
render(){
return (
home
{/* 1 */}
this.refName2=e}>home2
{/* 2 */}
home3
{/* 3 */}
home4
{/* 4*/}
)
}
}
```
### 处理路由
```
/* path: 路径 component: 组件 title:标题 exact: 是否精准匹配 children 子路由 icon: 图标 key:唯一标识*/
const routes = [
{
path:"/",
component:Home,
title:"Home",
exact:true,
icon:,
key:'1'
},
{
path:"/about",
title:"About",
icon:,
key:'2',
children: [
{
path:"/",
component: About,
title:"Abouts",
exact:true,
icon:,
key:'2-1'
},
{
path:"/detail",
title:"AboutDetail",
component: AboutDetail,
icon:,
key:'2-2'
}
]
},
{
path:"/404",
component:Error,
title:"404",
icon:,
isHide:true,
key:'3'
}
]
// 把多级路由展开成一级路由
/* routes: 路由 parentPath:拼接路径 parentKey:父级的key */
function flatRoutes(routes,parentPath = "", parentKey = []){
let arr = [];
for(let i = 0; i < routes.length; i++){
if(!routes[i].children){
const obj = {...routes[i]};
obj.parentKey = parentKey;
if(parentPath){
obj.path = parentPath + obj.path;
}
arr.push(obj);
}else{
const results = flatRoutes(routes[i].children,parentPath + routes[i].path,[...parentKey,routes[i].key]);
arr = [...arr,...results];
}
}
return arr;
}
const allRoutes = flatRoutes(routes);
const renderMenus = (routes, parentPath = "", parentKey = [])=>{
const menus = routes.map((item)=>{
if(item.isHide){
return "";
}
if(item.children){
return (
{renderMenus(item.children,parentPath+item.path,[...parentKey,item.key])}
)
}else{
return (
{item.title}
)
}
})
return menus;
}
{props.routes.map(item => (
))}
```
### redux
```
export const ADDROUTE = 'addRoute'
export const REMOVEROUTE = 'removeRoute'
export const SELECTTAB = 'selectTab'
export const SETPARENT = 'setParent'
import {ADDROUTE,REMOVEROUTE,SELECTTAB,SETPARENT} from '../constants'
// 添加路由
export const addRoute = data => ({type:ADDROUTE,data});
// 删除路由
export const removeRoute = data => ({type:REMOVEROUTE,data});
// 选择Tab
export const selectTab = data => ({type:SELECTTAB,data});
// 选中设置路由的父节点
export const setParent = data => ({type:SETPARENT,data});
import { combineReducers } from 'redux'
import routes from './routes'
import home from './home'
...
export default combineReducers({routes,home});
const routes = (state = initState, action)=>{
const {type,data} = action;
switch(type) {
case ADDROUTE:{
const isExist = state.data.some((item)=>{
return item.path === data.path
})
if(!isExist){
state.data = [...state.data,data];
setLocalStorage(state.data);
}
state.parentKey = data.parentKey
return {...state};
};
case REMOVEROUTE:{
state.data = state.data.filter((item)=>{
return item.path !== data;
});
setLocalStorage(state.data);
return {...state};
};
case SELECTTAB:{
state.activeRoute = allRoutes.find((item)=>{
return item.path === data;
})
state.parentKey = state.activeRoute.parentKey;
return {...state};
};
case SETPARENT:{
state.parentKey = data;
return {...state};
}
default: return state;
}
}
import { createStore,applyMiddleware } from 'redux';
import reducers from './reducers';
import thunk from 'redux-thunk';
const store = createStore(reducers,applyMiddleware(thunk));
export default store;
import { connect } from 'react-redux';
const SideBar = (props)=>{
console.log(props.routes)
...
})
export default connect(
state=>({
routes:state.routes.data,
activeRoute:state.routes.activeRoute,
parentKey:state.routes.parentKey
}),
{
addRoute,
selectTab,
setParent
}
)(withRouter(SideBar));
```