First00 2020-02-02
?个?够复杂的?程,需要尽量将功能解耦。什么叫解耦?简单来说,需要将不同的功能分开到不同的?件中,或不同的?录结构中,形成?个个模块,模块之间通过有限的接?交互,模块内部的数据变化对外部隐藏。
在 Node.js 上,这?点表现的?常不错。Node.js 实现了 CommonJS 规范,每个 JS ?件就是?个模块,模块中的所有数据对外隐藏,仅通过 Module.exports 暴露模块内的内容。于是,模块化开发在 Node.js 环境中已不成问题。
1. ?个 JavaScript ?件,即?个模块。
2. 模块中所有的数据,除?导出,否则都是私有数据,仅能在模块中访问。
3. 使? export 关键字导出模块。
4. 使? import 关键字导?模块,导?时使?解构表达式得到导出的数据,否则,将使?导出的默认
数据。
5. ?个模块可以有多个导出。
6. 导?的模块会被缓存。
7. 在??中加载??模块使? <script type="module" src="??模块">
一、模块导出
1、导出数据,定义一个变量,将要导出的数据赋值给变量,通过export导出
// 导出数据 export var color = "red"; export let name = "Nicholas"; export const magicNumber = 7;
2、导出函数,在函数前加上export导出
// 导出函数
export function sum(num1, num2) { 
 return num1 + num2;
}3、导出类,在类class前加上export导出
// 导出类
export class Rectangle {
 constructor(length, width) { 
 this.length = length; 
 this.width = width;
 }
}4、也可将定义的私有函数导出,通过export对象导出
// 定义?个函数
function multiply(num1, num2) { 
 return num1 * num2;
}
// 稍后将其导出
export {
 multiply
};以上方法最终能够得到的结果为:
{
 color: "red",
 name: "Nicholas",
 magicNumber: 7,
 sum: function,
 Rectangle: class,
 multiply: function
}二、模块导?
import { color, name, multiply } from "./mymodule.js";这是导入模块的基本形式。
也可使用通配符(*)导入模块中的所有东西:
import * as all from "./mymodule.js"; // all 可以是任意的名称 // 导?后,all 是?个对象,包含模块中导出的所有内容
注意,export 与 import 都有?个重要的限制,那就是它们必须被?在其他语句或表达式的外部。
if (flag) {
 export flag; // 语法错误
}
function tryImport() {
 import flag from "./example.js"; // 语法错误
}以上的导出导入方法就是错误的!
三、导?导出默认值
为了简化导?导出语法,还提供了?种导?导出的?式:默认值。使?这种?式导?导出会更加简单,但要注意的是,每个模块只能导出?个默认值。
export default function(num1, num2) { 
 return num1 + num2;
}<script type="module" src="./app.js"></script>

在base文档中书写以下代码:
export default class { //登录页面的视图
    constructor({
        el
    }) { //element
        this.el = el;
        this.init();
    }
    init() {
        this.render();
        this.mounted();
        this.handle();
    }
    render() { //负责页面渲染
       
    }
    mounted() { //负责挂载其他操作
    }
    handle() { //负责事件监听的
       
    }
}使用导出默认值的方式导出。
之后再主info.js中导入:
import Base from "./base.js";
之后就可以在info.js中使用继承了:

页面的渲染,事件监听都做好后就可以将其整体再次默认导出,在路由router文档中建立url接口,导入浏览器需要显示的info.js:
import info from "./view/info.js";
import addBooks from "./view/books/addBooks.js";
import updateBooks from "./view/books/updateBooks.js";
var routes = {
    ‘/info‘: {
        on: function () {
            new info({
                el: "#root"
            })
        },
        ‘/addBooks‘: function () {
            new addBooks({
                el: "#root"
            })
        },
        ‘/updateBooks‘: function () {
            new updateBooks({
                el: "#root"
            })
        }
    }
};
var router = Router(routes);
export default {
    init() {
        router.init(); //初始化路由
        location.hash = location.hash || "/info"; //有锚点就不会回到第一个锚点
    }
};在进行new的时候,最好使用与导出的标识符相同的单词,这样import会自动出现,避免书写麻烦,或错误导致无法联通。
总的来说,浏览器的模块化开发就是将页面渲染、事件监听进行包裹,整体的导出导入,达到我们一开始说的“形成?个个模块,模块之间通过有限的接?交互,模块内部的数据变化对外部隐藏。”,虽然前期的学习这种方式容易使人混乱,但是让我们的代码实现了工程化,每一个文档都有自己独立的目的,让我们的代码维护更加方便。