[关闭]
@xiaoqq 2017-01-04T02:43:30.000000Z 字数 4704 阅读 1216

LazilyLoad库使用帮助

Webpack


在页面中引用LazilyLoad库

  1. import LazilyLoadFactory, { CreateLazilyModule } from '../../utils/LazilyLoad'

LazilyLoad库常用方法

(1) LazilyLoadFactory(Component, modulesName):

可以使用LazilyLoadFactory来代替每个页面的import方法,实现每个页面依赖项的懒加载。
modulesName可以为字符串或字符串数组。
Demo:

  1. class PageTest extends React.Component {
  2. render() {
  3. const { Breadcrumb, Table, Pagination } = this.props;
  4. return (
  5. <div id="page-test">
  6. <Breadcrumb menuDataList={this.props.menuDataList} />
  7. ...
  8. </div>
  9. )
  10. }
  11. }
  12. PageTest = LazilyLoadFactory(PageTest, ["Breadcrumb", "CTable", "Pagination"])

(2) CreateLazilyModule(modulesName, moduleFn)

moduleFn为render函数,并且依赖于一个或多个模块(modulesName)。
比如:moduleFn中包含一个弹窗,弹窗中的组件并不希望其马上被加载,而是在弹窗显示的时候才会去异步加载。
modulesName可以为字符串或字符串数组。
Demo:

  1. renderDatePicker = ({DatePicker}) => {
  2. return <DatePicker type="datetime" placeholder="请选择" onChange = {() => {
  3. Modal.alert(this.state.currentPage)
  4. }}/>
  5. }
  6. renderModuleEdit() {
  7. return (
  8. <div className="padding-20" id="edit-module">
  9. //renderDatePicker函数依赖的DatePicker,必须要在CreateLazilyModule中声明,
  10. {CreateLazilyModule("DatePicker", this.renderDatePicker)}
  11. </div>
  12. )
  13. }

如果要从renderModuleEdit函数向renderDatePicker传递参数,可以通过bind函数

  1. renderDatePicker(test, {DatePicker}) {
  2. return <DatePicker type="datetime" placeholder="请选择" onChange = {() => {
  3. Modal.alert(test + this.state.currentPage);
  4. }}/>
  5. }
  6. renderModuleEdit() {
  7. let test = "当前的页面是:";
  8. return (
  9. <div className="padding-20" id="edit-module">
  10. //我们可以使用bind函数给renderDatePicker绑定test参数
  11. {CreateLazilyModule("DatePicker", this.renderDatePicker.bind(this, test))}
  12. </div>
  13. )

源码:

  1. import React from 'react';
  2. /**
  3. * @function 支持异步加载的封装组件
  4. */
  5. export class LazilyLoad extends React.Component {
  6. constructor() {
  7. super(...arguments);
  8. this.state = {
  9. isLoaded: false,
  10. };
  11. }
  12. componentWillMount() {
  13. this.load(this.props);
  14. }
  15. componentDidMount() {
  16. this._isMounted = true;
  17. }
  18. componentWillReceiveProps(next) {
  19. if (next.modules === this.props.modules) return null;
  20. this.load(next);
  21. }
  22. componentWillUnmount() {
  23. this._isMounted = false;
  24. }
  25. load(props) {
  26. this.setState({
  27. isLoaded: false,
  28. });
  29. const {modules} = props;
  30. const keys = Object.keys(modules);
  31. Promise.all(keys.map((key) => modules[key]()))
  32. .then((values) => (keys.reduce((agg, key, index) => {
  33. agg[key] = values[index];
  34. return agg;
  35. }, {})))
  36. .then((result) => {
  37. if (!this._isMounted) return null;
  38. this.setState({modules: result, isLoaded: true});
  39. });
  40. }
  41. render() {
  42. if (!this.state.isLoaded) return null;
  43. return React.Children.only(this.props.children(this.state.modules));
  44. }
  45. }
  46. LazilyLoad.propTypes = {
  47. children: React.PropTypes.func.isRequired,
  48. };
  49. /**
  50. * 声明所有的组件及路径,这个对象需要不断更新
  51. * @type {Object}
  52. */
  53. const ComponentMap = {
  54. BaseTable: () => System.import('../components/basetable'),
  55. Breadcrumb: () => System.import('../components/breadcrumb'),
  56. CTable: () => System.import('../components/cTable'),
  57. DatePicker: () => System.import('../components/datepicker'),
  58. Dropdown: () => System.import('../components/dropdown'),
  59. Overlay: () => System.import('../components/overlay'),
  60. Pagination: () => System.import('../components/pagination'),
  61. InputSelect: () => System.import('../components/select/inputSelect'),
  62. NormalSelect: () => System.import('../components/select/normalSelect'),
  63. RealtimeSelect: () => System.import('../components/select/realtimeSelect'),
  64. }
  65. /**
  66. * 使用场景:组件Component依赖于一个或多个模块(modulesName),而且这些模块需要被异步加载
  67. * 比如:我们可以使用LazilyLoadFactory来代替每个页面的`import`方法,实现每个页面依赖项的懒加载
  68. * LazilyLoadFactory返回的是一个新的组件(本质上是一个函数)
  69. * @param {[type]} Component [description]
  70. * @param {[String Or Array]} modulesName [Component所需要异步加载的模块,modulesName的类型必须为字符串或字符串数组]
  71. * @return {[Component]} [description]
  72. */
  73. const LazilyLoadFactory = (Component, modulesName) => {
  74. let modules = {};
  75. if(modulesName instanceof Array) {
  76. modulesName.forEach(list => {
  77. if(!ComponentMap[list]) {
  78. console.error(`${list}组件未找到,请检查拼写。`);
  79. }
  80. modules = {...modules, [list]: ComponentMap[list]}
  81. });
  82. }else if(typeof(modulesName) == 'string') {
  83. if(!ComponentMap[modulesName]) {
  84. console.error(`${modulesName}组件未找到,请检查拼写。`);
  85. }
  86. modules[modulesName] = ComponentMap[modulesName]
  87. }else {
  88. console.error("ModulesName 必须为字符串或字符串数组。");
  89. return;
  90. }
  91. return (props) => (
  92. <LazilyLoad modules={modules}>
  93. {(mods) => <Component {...mods} {...props} />}
  94. </LazilyLoad>
  95. );
  96. };
  97. /**
  98. * 使用场景:moduleFn为一个render函数,并且依赖于一个或多个模块(modulesName)
  99. * 比如:moduleFn中包含一个弹窗,弹窗中的组件并不希望其马上被加载,而是在弹窗显示的时候才会去异步加载
  100. * CreateLazilyModule返回的是一个对象
  101. * @param {[type]} modulesName [description]
  102. * @param {[type]} moduleFn [Component所需要异步加载的模块,modulesName的类型必须为字符串或字符串数组]
  103. * @return {[Object]} [description]
  104. */
  105. export const CreateLazilyModule = (modulesName, moduleFn) => {
  106. let modules = {};
  107. if(modulesName instanceof Array) {
  108. modulesName.forEach(list => {
  109. if(!ComponentMap[list]) {
  110. console.error(`${list}组件未找到,请检查拼写。`);
  111. }
  112. modules = {...modules, [list]: ComponentMap[list]}
  113. });
  114. }else if(typeof(modulesName) == 'string') {
  115. if(!ComponentMap[modulesName]) {
  116. console.error(`${modulesName}组件未找到,请检查拼写。`);
  117. }
  118. modules[modulesName] = ComponentMap[modulesName]
  119. }else {
  120. console.error("ModulesName 必须为字符串或字符串数组。");
  121. return;
  122. }
  123. return (
  124. <LazilyLoad modules={modules}>
  125. {moduleFn}
  126. </LazilyLoad>
  127. )
  128. };
  129. export const importLazy = (promise) => (
  130. promise.then((result) => result)
  131. );
  132. export default LazilyLoadFactory;
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注