模块化开发
好处
- 可以避免变量重名,把功能独立成多个文件
- 每一个模块都有自己的作用域,利于团队开发
- 每个模块可以只开放部分api,实现按需导入
暴露api的几种方法
1:功能模块的具名导出
m7.js
//使用export对每一个需要导出的api进行具体导出
export let site = '好好学习';
export function show() {
return 'show function'
}
export class User{
static render() {
return 'user static'
}
}
2:统一导出
m8.js
let site = '好好学习';
function show() {
return 'show function'
}
class User{
static render() {
return 'user static'
}
}
export { site, User, show };
3:默认导出
m10.js
/**
* 当我们只有一个模块功能的时候,可以使用默认导出
* **/
export default class User{
static render() {
return 'user static render'
}
}
// 或者
// export {User as default}
导入api的几种方法
1:按需导入
3.html
//注意一定要在script标签里边声明type='module'
<script type="module">
// 导入要引用的模块
import { title, show } from "./xh.js";
// 如果需要全部导入的话
// import {} from './xh.js'
console.log(title);
console.log(show("我"));
</script>
xh.js
let title = '好好学习'
let url = '天天向上'
function show(name) {
console.log(name);
}
export {
title,show
} //开放title api
2:全部导入
8.html
<script type="module">
import * as api from "./m8.js";
console.log(api);
console.log(api.show());
</script>
m8.js
let site = '好好学习';
function show() {
return 'show function'
}
class User{
static render() {
return 'user static'
}
}
export { site, User, show };
如果在一个模块当中既有具名导出,也有默认导出,那么在导入的时候可以这么做
11.html
<script type="module">
// 混合导入导出的使用
import { site } from "./m11.js";
import xm from "./m11.js";
// 或者
// import xm,{site} from './m11.js'
</script>
m11.js
/**
* 当我们只有一个模块功能的时候,可以使用默认导出
* **/
export let site = '好好学习'
export default class User {
static render() {
return 'user static render'
}
}
// 或者
// export {User as default,site}
模块都是在最后才解析的,所以位置可以在body前面
<script type="module">
/**
* 模块是属于最后解析
* 如果不声明type='module',那么该语句就会报错,因为JS是从上往下执行的
* 使用模块是默认为严格模式
* */
console.dir(document.querySelector("button"));
</script>
<body>
<button>CLICK</button>
</body>
模块的作用域相当于是函数作用域而不是全局作用域
<script>
/**
* 如果不声明模块,即type='module'的话,在script中声明的变量等都是处于全局作用域
* 但是如果声明了模块,那么在模块里边声明的变量就是独立出来一个作用域,可以理解为是一个函数;外部访问不到
*
* **/
let site = "好好学习";
</script>
<script>
console.log(site);
</script>
模块具有预解析的特点,多次重复引入同一个功能,那么只会执行一次
<script type="module">
// JS模块的预解析,也即是即使多次导入,也只是只执行一次
import {} from "./xm.js";
import {} from "./xm.js";
import {} from "./xm.js";
import {} from "./xm.js";
import { obj } from "./xt.js";
console.log(obj);
/**
* 优点:当多个模块都含有某一个功能的时候,模块的预解析可以使得该功能只执行一次
* **/
</script>
xm.js
console.log('书山有路勤为径');
xt,js
class Lesson{
data = [];
init() {
this.data = [{ name: 'js' }, {name:'mysql'}]
}
get() {
return this.data
}
}
let obj = new Lesson();
obj.init()
export {obj}
给api使用别名
在导入或者导出的时候使用as即可
<script type="module">
// 变量重名导致报错,可以在导入的时候使用别名来避免重名报错
import { site as S, view } from "./m9.js";
let site = "天天向上";
console.log(S);
console.log(view("测试"));
</script>
m9.js
let site = '好好学习'
function show(params) {
console.log('我要打印的内容是:', params);
}
export {
show as view, site
}
按需动态加载模块
<script type="module">
// 按需动态加载模块
document.querySelector("button").addEventListener("click", () => {
import("./m13.js").then((module) => {
console.log(module.site);
});
});
</script>
m13.js
let site = '小灰';
let url = 'www.baidu.com'
export {site,url}
集成管理模块
m12.1.js
let site = '小灰';
let url = 'www.baidu.com'
export {
site,
url
}
m12.2.js
export default class User {
show() {
console.log('书山有路勤为径');
}
}
export let web = '苦海无涯苦作舟'
m12.index.js
import * as m121 from './m12.1.js';
import * as m122 from './m12.2.js';
export {m121,m122}
m12.js
import * as api from './m12.index.js'
console.log(api);
12.html
<script type="module" src="./m12.js"></script>