第三節:ES6模塊化歷史 及 默認、按需、直接導入導出、Vue單文件


一. 模塊化歷史

1. 瀏覽器端模塊化

 (1). AMD(Asynchronous Module Definition,異步模塊定義) :代表產品為:Require.js 

 (2). CMD(Common Module Definition,通用模塊定義) :代表產品為:Sea.js

2. 服務器端模塊化

服務器端的模塊化規范是使用CommonJS規范:

 (1).使用require引入其他模塊或者包

 (2).使用exports或者module.exports導出模塊成員

 (3).一個文件就是一個模塊,都擁有獨立的作用域

3. 大一統的ES6模塊化

 (1).每一個js文件都是獨立的模塊

 (2).導入模塊成員使用import關鍵字

 (3).暴露模塊成員使用export關鍵字

PS: 推薦使用ES6模塊化,因為AMD,CMD局限使用與瀏覽器端,而CommonJS在服務器端使用。 ES6模塊化是瀏覽器端和服務器端通用的規范. 

 

二. ES6模塊化

1. 匹配規則

(1). 如果是完整路徑,則直接引入 。eg:import moudleA from "./find.js";

(2). 如果不是完整路徑,比如:import mA from  './find'

 A. 先找同名的js文件,即找 find.js

 B. 如果找不到,再找find文件夾,找到后,再匹配find文件夾中的index.js文件。

 C. 如果找不到index.js文件,會去當前文件夾中的package.json文件中查找main選項中的入口文件

 D. 全都沒有的話,則報錯

2. 默認導出、導入

(1). 默認導出

A. 模式1 (def1.js)

/*
   默認導出 
   1. 使用 export default 進行導出
   2. 1個js文件中只能有1個 export default
 */

// 1. 變量
let userName1 = 'ypf1';
let age1 = 20;

// 2. 方法
function getInfo1() {
    return {
        school1: 'bejing1',
        street1: 'zhonghan1'
    }
}

function getInfo2() {
    return "hello vue3";
}

// 對外導出
export default {
    userName1,
    age1,
    getInfo1,
    getInfo2
}

B. 模式2 (def2.js)

/*
   默認導出 
   1. 使用 export default function(){} 直接導出1個函數, 接收的時候仍然需要用對象接收

 */

export default function(){
    return {
        school2: 'bejing2',
        street2: 'zhonghan2'
    }
}

(2). 默認導入

A. 必須用一個對象接收,對象名任意,不加{}
B. 如果接收的是export default function(){}形式的導出,這里的接收對象,就直接是函數了

<script>
    /* 一. 接收默認導出 
     * 1. 必須用一個對象接收,對象名任意,不加{}
     * 2. 如果接收的是export default function(){}形式的導出,這里的接收對象,就直接是函數了
     */
    import myDef1 from './01_默認導出/def1.js';
    import myDef2 from './01_默認導出/def2.js';

    export default {
        setup() {
            // 一. 測試默認導出
            // 1. 形式1
            {
                console.log('-------測試默認導出_形式1------------')
                console.log(myDef1.userName1, myDef1.age1);
                var obj1 = myDef1.getInfo1();
                console.log(obj1.school1, obj1.street1);
                // 或者直接解構
                const { school1, street1 } = myDef1.getInfo1();
                console.log(school1, street1);
                var obj2 = myDef1.getInfo2();
                console.log(obj2);
            }
            // 2. 形式2
            {
                console.log('-------測試默認導出_形式2------------')
                var obj1 = myDef2(); //注:這里myDef2直接就是函數了
                console.log(obj1.school2, obj1.street2);
                // 或者直接解構
                const { school2, street2 } = myDef2();
                console.log(school2, street2);
            }
            
        }
    }
</script>

3. 按需導出、導入 

(1). 按需導出

 A. 使用 export + 變量,或 export +方法,進行逐個導出 (詳見need1.js文件)

 B. 也可以先聲明,然后通過 eport {} 進行選擇性的導出   (詳見need2.js文件)

 C. 以上兩種方式共存 (詳見need3.js) 

need1.js

// 1. 變量
export let userName1 = 'ypf1';
export let age1 = 20;

// 2. 方法
export function getInfo1() {
    return {
        school1: 'bejing1',
        street1: 'zhonghan1'
    }
}

export function getInfo2() {
    return "hello vue3";
}

need2.js

let age3=88;
let name3='ypf3';

function getInfo3(){
    return 'hello info3';
}

export {
    age3,
    getInfo3
}

need3.js

/*
   按需導出 
   1. 使用 export + 變量,或 export +方法, 與  eport {}   共存
 */

export let mySchool1='beijing1';

let mySchool2='beijing2';
function checkLogin(){
    return 'ok';
}
export {
    mySchool2,
    checkLogin
}

(2). 按需導入

 A. 必須使用 {} 接收,且接收的名稱要和導出的名稱一致

 B. 如果想改名稱,可以使用as,比如 {userName1 as myName1}

<script>
    /* 二. 接收按需導出
     * 1. 必須使用 {} 接收,且接收的名稱要和導出的名稱一致
     * 2. 如果想改名稱,可以使用as,比如 {userName1 as myName1}    
     */
    import { userName1, age1 as myAge1, getInfo1, getInfo2 } from './02_按需導出/need1.js';
    import { age3, getInfo3 } from './02_按需導出/need2.js';
    import {mySchool1,mySchool2,checkLogin} from './02_按需導出/need3.js';
    
    export default {
        setup() {
            
            // 二. 測試按需導出
            // 1. 形式1
            {
                console.log('-------測試按需導出_形式1------------')
                console.log(userName1, myAge1);
                var obj1 = getInfo1();
                console.log(obj1.school1, obj1.street1);
                // 或者直接解構
                const { school1, street1 } = getInfo1();
                console.log(school1, street1);
                var obj2 = getInfo2();
                console.log(obj2);
            }
            // 2.形式3
            {
                console.log('-------測試按需導出_形式2------------')
                console.log(age3);
                var obj1 = getInfo3();
                console.log(obj1);
            }
            // 3. 形式3-共存
            {
                console.log('-------測試按需導出_形式3_共存------------')
                console.log(mySchool1,mySchool2);
                var obj1 = checkLogin();
                console.log(obj1);
            }
        }
    }
</script>

4. 統一入口

 通過1個index.js文件作為中轉,從而引入多個js 

 詳見里面的hook封裝位置:https://www.cnblogs.com/yaopengfei/p/15390818.html

5. 直接運行

// 四. 直接運行的代碼
import './04_直接運行/test1.js'

注:如何運行呢?

 nodejs中不能直接執行ES的模塊化寫法,需要npm init一下,然后在package.json中,加上一句話:  "type": "module",  

 

三. Vue單文件

1. 傳統Vue組件的缺陷

  全局定義的組件不能重名,字符串模板缺乏語法高亮,不支持css(當html和js組件化時,css沒有參與其中)  沒有構建步驟限制,只能使用H5和ES5,不能使用預處理器(babel)

2. 解決方案

 使用Vue單文件組件,每個單文件組件的后綴名都是.vue 每一個Vue單文件組件都由三部分組成

(1).template組件組成的模板區域

(2).script組成的業務邏輯區域

(3).style樣式區域

代碼如下: 

<template>

    組件代碼區域

</template>

<script>

    js代碼區域

</script>

<style scoped>

    樣式代碼區域

</style>

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM