国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網(wǎng)站 > WEB開發(fā) > 正文

react按需加載

2024-04-27 15:12:12
字體:
供稿:網(wǎng)友

react-router webpack 按需加載,與路由權(quán)限控制

說明

當(dāng)網(wǎng)站規(guī)模越來越大,通過webpack 打包后的 react 項目也會越來越大,這會導(dǎo)致首頁渲染時間變長,影響用戶體驗,webpack 提供了一種按需加載的方式,需要結(jié)合 react-router 使用,他會將代碼拆分成多個小包,需要哪個部分就加載響應(yīng)的包。

webpack 配置

首先需要對 config 文件修改一下,如下

output: { path: path.join(__dirname, 'dev'), // 輸出路徑 filename: '/js/bundle.js', // 輸出文件名 publicPath: path.join(__dirname, 'dev'), // 必填項 chunkFilename : '/js/routes/[name].chunk.js?[chunkhash:10]', // 按需加載輸出的文件名 },

路由配置頁(app/js/routes.js

react 按需加載,關(guān)鍵是讓路由動態(tài)加載組件,react-router 提供了一個屬性 getComponent ,它與 component 屬性一樣,但是是異步的,當(dāng)路由匹配時才會調(diào)用這個方法,常用于代碼分割; 相關(guān)內(nèi)容查看 API文檔

webpack 為我們提供了一個按需加載函數(shù) require.ensure(dependencies, callback, chunkName)

dependencies : 依賴的模塊數(shù)組callback : 回調(diào)函數(shù),該函數(shù)調(diào)用時會傳入一個 require 參數(shù)chunkName : 模塊名,用于構(gòu)建時生成文件名

更多了解,查看官方文檔

一般寫法
/* app/js/routes.js 路由配置文件 */ import React from 'react'; import { Route, IndexRoute} from 'react-router'; // 引入容器組件 import App from './containers/App'; export default ( <Route path="/" component={App}> <IndexRoute getComponent={(location, cb) => { require.ensure([], require => { cb(null, require('./containers/Login.js').default) },'login'); }} /> <Route path="home" getComponent={(location, cb) => { require.ensure([], require => { cb(null, require('./containers/Home.js').default) },'home'); }} /> <Route path="login" getComponent={(location, cb) => { require.ensure([], require => { cb(null, require('./containers/Login.js').default) },'login'); }} /> </Route> );

注意:cb(null, require('./containers/Login.js').default) 因為我用 es6 的 export default 導(dǎo)出的組件,所以 require 之后要加上 default,如果使用 module.export 導(dǎo)出組件 則不需要加 default

拆分寫法

以上寫法在 路由層級或者數(shù)量較多的時候會比較臃腫,所以還需要對路由進(jìn)行拆分

路由拆分,需要對目錄結(jié)構(gòu)做一下改變,在js 文件夾下添加 routes 路由配置文件夾

|---js | |---actions | | | |---components | | | |---containers | | | |---reducers | | | |---store | | | |---routes | | |---login.js // 主路由的下一級路由 | | |---login // login 路由的下一級路由目錄 | |---constants.js // 靜態(tài)常量 | |---index.js // 項目入口文件 | |---routes.js // 路由配置主文件 |

routes.js 路由配置的主文件

const routes = { path : '/', // 將匹配的路由,對應(yīng)標(biāo)簽中的 path 屬性 indexRoute: { // 設(shè)置默認(rèn)顯示頁面,對應(yīng)標(biāo)簽中的 IndexRoute 組件 getComponent(nextState, cb) { require.ensure([], (require) => { cb(null, require('./containers/Login').default); }, 'Login'); } }, // childRoutes:[] // 子 route 的一個數(shù)組,與在 JSX route 配置中的 children 一樣。 getChildRoutes(partialNextState, cb) { // 與 childRoutes 一樣,但是是異步的,并且可以接收 partialNextState(location 信息) require.ensure([], (require) => { cb(null, [ require('./routes/login'), require('./routes/home'), require('./routes/error') ]) }) }, getComponent(nextState, cb) { // 定義對應(yīng)的組件,對應(yīng)標(biāo)簽中的 component 屬性,但是是異步的,路由匹配時才會調(diào)用這個方法 require.ensure([], (require) => { // require.ensure : webpack 提供的按需加載方法 cb(null, require('./containers/App').default); }, 'App'); } } export default routes;

js/routes/home.js 路由分支

module.exports = { path: 'home', getChildRoutes(partialNextState, cb) { require.ensure([], (require) => { cb(null, [ require('./home/page'), require('./home/student'), require('./home/admin') ]) }) }, getComponent(nextState, cb) { require.ensure([], (require) => { cb(null, require('../containers/Home').default) }, 'Home') } }

路由權(quán)限控制

基本思路 : 每當(dāng)指定路由要發(fā)生改變,就使用一個中間服務(wù),介于上一級路由和將要到達(dá)路由之間啟動,來判斷我們是否有進(jìn)入這個路由的權(quán)限,React 中的 <Route /> 提供了一個 onEnter方法,表示正要進(jìn)入這個路由,在這里判斷進(jìn)入權(quán)限,可以修改要進(jìn)入的頁面

<Route path="home" getComponent={(location, cb) => { require.ensure([], require => { cb(null, require('./containers/Home.js').default) },'home'); }} onEnter={request}/>function request(nextState, replace, next){ let auth = nextState.location.query.auth; if(auth === 'home'){ next(); } else if (auth === 'other') { replace('/other'); next(); } else { replace('/'); next(); }}

注:nextState : 表示跳轉(zhuǎn)后的location 信息;replace 用于 更改下一個進(jìn)入的頁面地址,但是不會跳轉(zhuǎn);next : 用于跳轉(zhuǎn)頁面,沒有其他操作則顯示當(dāng)前路由對應(yīng)頁面

如果使用路由拆分,如下

module.exports = { path: 'home', getChildRoutes(partialNextState, cb) { require.ensure([], (require) => { cb(null, [ require('./home/page'), require('./home/student'), require('./home/admin') ]) }) }, getComponent(nextState, cb) { require.ensure([], (require) => { cb(null, require('../containers/Home').default) }, 'Home') }, onEnter: (nextState, replace, next) => { console.log(nextState.location.state); let isAuth = nextState.location.state.isAuth; if (isAuth === 'student' || isAuth === 'teacher' || isAuth === 'admin') { next(); } else { replace('/error'); next(); } } }
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 郸城县| 房产| 玉山县| 建始县| 台北县| 葵青区| 洞口县| 手游| 北流市| 密山市| 贵德县| 延寿县| 山东省| 浠水县| 黔东| 晋中市| 怀安县| 东海县| 峡江县| 新建县| 新郑市| 陵川县| 抚州市| 左权县| 通渭县| 名山县| 宜兴市| 定西市| 富阳市| 九龙县| 南皮县| 滨州市| 金昌市| 广灵县| 社旗县| 靖西县| 济源市| 宁城县| 遂溪县| 张北县| 长海县|