前言:此文需要有一定react,redux基礎(chǔ),具體學(xué)習(xí)資料請(qǐng)科學(xué)上網(wǎng)。
成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),鎮(zhèn)江企業(yè)網(wǎng)站建設(shè),鎮(zhèn)江品牌網(wǎng)站建設(shè),網(wǎng)站定制,鎮(zhèn)江網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,鎮(zhèn)江網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
使用create-react-app腳手架
具體基礎(chǔ)配置請(qǐng)參考
配合antd組件實(shí)現(xiàn)的管理系統(tǒng)demo,線上地址
開(kāi)發(fā)前反思
1. 按需加載
webpack的 import 動(dòng)態(tài)加載的模塊的函數(shù),import(參數(shù)),參數(shù)為模塊地址。
注意: import 后會(huì)返回一個(gè)promise對(duì)象。
import('/components/chart').then(mud => { dosomething(mod) });
本demo構(gòu)建了異步加載組件Bundle,具體代碼請(qǐng)見(jiàn)
class Bundle extends Component { constructor(props) { super(props); this.state = { mod: null }; } unmount = false componentDidMount = () => { // 加載組件時(shí),打開(kāi)全局loading this.props.dispatch(loading(true)) this.load(this.props) } componentWillUnmount = () => { this.unmount = true } componentWillReceiveProps(nextProps) { if (nextProps.load !== this.props.load) { this.load(nextProps) } } load(props) { if (this.state.mod) { return true } //注意這里,使用Promise對(duì)象; mod.default導(dǎo)出默認(rèn) props.load().then((mod) => { if (this.unmount) { // 離開(kāi)組件時(shí),不異步執(zhí)行setState this.props.dispatch(loading(false)) return false } this.setState({ mod: mod.default ? mod.default : mod }, _ => { // 組件加載完畢,關(guān)閉loading this.props.dispatch(loading(false)) }); }); } render() { return this.state.mod ? this.props.children(this.state.mod) : null; } }
具體使用
import('路徑')}> {Comp => { return Comp ? : 加載中...}}
2. 全局loading
配合redux,dispatch => reducer更新 => mapstate更新,在根組件進(jìn)行l(wèi)oading的渲染
詳細(xì)請(qǐng)見(jiàn)本demo地址 src/routers/router.js——render函數(shù)
3. 配置路由對(duì)象
項(xiàng)目布局如下
本demo使用的是router4,官方文檔演示為單行Route(如vue種的router),未有統(tǒng)一配置對(duì)象。 管理系統(tǒng)基本圍繞著content進(jìn)行業(yè)務(wù)開(kāi)發(fā),構(gòu)建通用配置有助于開(kāi)發(fā) 構(gòu)建router.config.js
const routers = [ { menuName: '主頁(yè)', menuIco: 'home', component: 'home/home.js', // 主頁(yè) path: '/admin/home' // 主頁(yè) }, { menuName: '用戶', menuIco: 'user', children: [ { menuName: '用戶列表', component: 'user/list.js', // 主頁(yè) path: '/admin/user/list' // 主頁(yè) } ] }, { menuName: '多級(jí)菜單', menuIco: 'setting', children: [ { menuName: '多級(jí)菜單2', children: [ { menuName: '菜單', component: 'user/list.js', // 主頁(yè) path: '/admin/user/list3' // 主頁(yè) } ] } ] }, { menuName: '關(guān)于我', menuIco: 'smile-o', component: 'about/about.js', // 主頁(yè) path: '/admin/about' // 主頁(yè) } ]
實(shí)現(xiàn)思路,最外層布局為Admin,content被Admin包裹,那么可以利用 this.props.children ,把內(nèi)容打入content中。(利用bundle組件異步加載后塞入組件進(jìn)行渲染)
// Content組件內(nèi)部 render() { return ( {this.props.children} {this.props.children}) } // 本demo實(shí)現(xiàn),詳見(jiàn)src/routers/router.js( {initRouters.map(el => this.deepItem(el, { ...this.props, ...item}))} )} />
4. 配置通用reducer
多人配合開(kāi)發(fā),一些業(yè)務(wù)場(chǎng)景的組件需要狀提升(不理解狀態(tài)提升的同學(xué),請(qǐng)科學(xué)上網(wǎng))
import otherReducers from './otherReducers' const App = combineReducers({ rootReducers, ...otherReducers // 其他需要增加的reducers })
5. 登陸驗(yàn)證
利用 withRouter 函數(shù),頁(yè)面進(jìn)行路由跳轉(zhuǎn)時(shí)觸發(fā)該函數(shù)
const newWithRouter = withRouter(props => { // .... })
若未登錄,則返回
return
6. 路由攔截
同上,根據(jù)路由配置與權(quán)限,返回相應(yīng)的菜單或屏蔽
return
7 其他配置
7-1. 自定義樣式
// 修改webpack.config.dev.js 和 webpack.config-prod.js 配置文件 { test: /\.(css|less)$/, // 匹配src的都自動(dòng)加載css-module include: [/src/], exclude: [/theme/], use: [ require.resolve('style-loader'), { loader: require.resolve('css-loader'), options: { importLoaders: 1, modules: true, // 新增對(duì)css modules的支持 localIdentName: '[path]___[name]__[local]___[hash:base64:5]' } }, { loader: require.resolve('postcss-loader'), options: { // Necessary for external CSS imports to work // https://github.com/facebookincubator/create-react-app/issues/2677 ident: 'postcss', plugins: () => [ require('postcss-flexbugs-fixes'), autoprefixer({ browsers: [ '>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9', // React doesn't support IE8 anyway ], flexbox: 'no-2009' }) ] } }, { loader: require.resolve('less-loader') // compiles Less to CSS } ] }, { // 不匹配node_modules,theme的都不能自動(dòng)加載css-module test: /\.(css|less)$/, include: [/node_modules/,/theme/], use: [ { loader: "style-loader" }, { loader: "css-loader", options: { importLoaders: 1 } }, { loader: require.resolve('less-loader') // compiles Less to CSS } ] },
使用: 在App.js中直接導(dǎo)入
import './assets/theme/App.less'
7-2. 熱更新
步驟一:
// 安裝react-hot-loader npm install --save-dev react-hot-loader
步驟二:
在webpack.config.js 的 entry 值里加上 react-hot-loader/patch
步驟三:
webpackDevServer.config.js中hot設(shè)置為true
步驟四: 在webpack.config.dev.js中在babel-loader中plugins加入react-hot-loader/babel
{ test: /\.(js|jsx|mjs)$/, include: paths.appSrc, loader: require.resolve('babel-loader'), options: { // This is a feature of `babel-loader` for webpack (not Babel itself). It // enables caching results in ./node_modules/.cache/babel-loader/ directory for // faster rebuilds. cacheDirectory: true, plugins: [ 'react-hot-loader/babel' ] } },
步驟五:
重寫(xiě)index.js,App掛載
import { AppContainer } from 'react-hot-loader' const render = Component => { ReactDOM.render(, document.getElementById('root') ) } render(App) if(module.hot) { module.hot.accept('./App',() => { render(App); }); }
7-3. 本地瀏覽
直接在package.json中 加入
homepage:'.'
后記:使用react與vue的感悟
react是函數(shù)式編程,代碼難度、學(xué)習(xí)曲度、裝逼指數(shù),社區(qū)生態(tài)多樣性相比vue更高一點(diǎn)。
vue提供了大量的指令降低了開(kāi)發(fā)難度,詳細(xì)完善的文檔,上手更快。
react提供較少的api,相比vue的指令,業(yè)務(wù)場(chǎng)景的功能需要自己實(shí)現(xiàn),難度更高一點(diǎn)
vue適合中小型項(xiàng)目,單兵、少量人員配合快速開(kāi)發(fā)
react適合大型項(xiàng)目,多人協(xié)作
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。