拿到设计时,我们首先要把项目划分为一个个模块,或者组件
划分原则:
按照功能和需求划分:普通业务模块/ 组件
按照复用性划分:通用业务模块
通用功能模块组件【UI组件库】
1.1 模块化演化进程 未来的项目一定是 模块化/组件化 开发!!
模块化编程进化历史
单例设计模式
AMD「require.js」
CommonJS(node.js)
CMD「sea.js」
ES6Module
1.2单例设计模式 也就是原生js写法,用<script src>
,调用文件,把各个功能写在不同的模块下,最后合并到页面中。
问题 :
会出现全局变量污染,也就是模块间会有相互冲突。
模块间相互引用问题,用window方法多了后也会冲突
解决问题 :
如此单例设计模式就完成了。
注意 :包导入的顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let xxxModule = (function ( ) { let time = new Date (); const query = function query ( ) { }; const handle = function handle ( ) { }; return { query, handle }; })();
没看例子:p132 37:17~52:30
不足之处 :需要手动分析模块之间的依赖关系,按顺序依次导入相关模块;所有模块都是基于script一个个导入的,这样页面HTTP请求变多!
1.3 AMD「require.js」 https://requirejs.org
优势 :在保证模块之间独立和可以相互访问的基础上,HTML中无需再导入各个模块了「不存在顺序问题 」,也不需要自己去分析相互间的依赖关系!不足 :依赖模块的导入是“前置导入”,只有把依赖模块动态导入完毕,才会触发回调函数执行「阻碍代码执行速度」;代码书写的顺序也不是很方便;可能存在重复导入;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 require .config ({ baseUrl : 'js/lib' , }); require (['moduleB' , 'moduleA' ], function (moduleB, moduleA ) { console .log (moduleB.average (10 , 20 , 30 , 40 , 50 )); }); define (function ( ) { return { sum (...args ) { let len = args.length , firstItem = args[0 ]; if (len === 0 ) return 0 ; if (len === 1 ) return firstItem; return args.reduce ((total, item ) => { return total + item; }); } }; }); define (['moduleA' ], function (moudleA ) { return { average (...args ) { let len = args.length , firstItem = args[0 ]; if (len === 0 ) return 0 ; if (len === 1 ) return firstItem; args.sort ((a, b ) => a - b); args.pop (); args.shift (); return (moudleA.sum (...args) / args.length ).toFixed (2 ); } }; });
没看例子:p132 58:17~1:20:05
1.4 CommonJS模块化规范
node.js出现了,不用导入
每创建一个js文件就创建了一个模块,里面的代码就是独立的。用module.exports
导出对象。
唯一的问题:浏览器端不支持CommonJS规范 淘宝“玉伯”仿照CommonJS规范,研发了一款插件 sea.js ,旨在把CommonJS规范搬到浏览器端运行「这种模块思想被称之为CMD」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const sum = function sum (...params ) { return params.reduce ((result, item ) => { return result + item; }); }; module .exports = { sum }; let name = '哈哈' ;let A = require ('./A' );const average = function average (...params ) { return (A.sum (...params) / params.length ).toFixed (2 ); }; module .exports = { average }; let A = require ('./A' );console .log (A.sum (10 , 20 , 30 , 40 ));let B = require ('./B' );console .log (B.average (10 , 20 , 30 , 40 ));
缓存机制
还是没有实战—27:35
1.5 ES6Module模块规范 https://es6.ruanyifeng.com/#docs/module
可以直接运行在浏览器端;不支持IE;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 使用在html文件上时,导入文件前要加入type = module ,预览要使用http协议(LiveServer ),不能使用File 协议。 模块的导入导出: 整体来讲,每个模块导出的是一个Module 对象,我们可以基于 export /export default 为对象中加入导出的内容 @导出方法1 export default xxx; + xxx可以是任意类型值 + 给Module 对象新增一个 “default ” 属性,属性值就是导出的值 + 在一个模块中,export default 只允许出现一次 @导出方法2 export 创建值的表达式(声明变量 = 值); let num = 10 ; export num; export let num = 10 ; --- let num = 10 ; export { num, x :100 }; --- + export 可以出现多次,导出多个内容 + 声明的变量叫啥名字,最后给Module 对象加入的是同名的属性名,属性值就是变量的值
1.5.2导入方法 我们会基于 import 方法导入模块「导入模块导出的内容」
import N from ‘模块地址(在浏览器端不能忽略.js后缀名)’;
N获取的不是整个导出的Module对象,仅仅获取的是Module中default这一项的值 不能在import期间,直接对N解构赋值,因为涉及解构赋值就会变为另外一种情况
解构赋值:import {x,y} from ‘模块地址’;
直接对导出的Module对象中(排除default属性),导出的内容进行解构赋值
import * as M from ‘模块地址’;先导入所有导出的内容,赋值给M变量
还是没有细看