# 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 的后台管理模板,包含侧边栏、头部导航标签和需要导航跳转的主要页面 ![avatar](/src/images/page.jpg) ### 拉取使用 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)); ```