Vue初學24-前端模塊化

前端模塊化的原因

隨着前端的功能越來越複雜,代碼量越來越多。如果衆多的js文件不採用模塊化的方式管理,勢必會遇到一個問題,那就是全局變量重名。相信很多前端開發者都遇到過這個問題。。。

實際項目開發中,通常不同人有不同的分工,分別負責不同的功能模塊。

假設A在part1.js中定義了全局變量tag,並賦了值,B在part2.js中恰好也定義了同名變量tag,也對tag賦了值,那麼tag作爲全局變量,它的值取決於part1.js和part2.js的執行順序,值具有不確定性。如果a在其他js文件(part3.js)中再想用part1.js中tag的值,數據可能會不一致。

part1.js

var tag=true;
var name='a';

function add(a,b)
{
    return a+b;
}
console.log('我是a');

part2.js

var tag=false;
var name='b';

console.log('我是b');

part3.js

if(tag)
{
    console.log('我使用了part1中的tag');
}

 三個js的引用順序如下:

<body>
<script src="../js/part1.js"></script>
<script src="../js/part2.js"></script>
<script src="../js/part3.js"></script>
</body>

part2.js中tag的值覆蓋了part1.js的值,當a在part3.js中使用tag時,tag的值已經發生了改變。

結果如下:並沒有輸出part3.js中的“我使用了part1中的tag”這句話。

通過匿名函數實現模塊化

要讓part1.js,part2.js,part3.js互不影響,擁有獨立的作用域,可以考慮採用匿名函數。但是,part3.js中想要引用part1.js中的變量,因此,也不能完全獨立,part3.js中要能訪問到part1.js中的變量或者函數。修改如下:

part1.js

通過匿名函數實現作用域的隔離,使各個js文件互不影響。爲了讓其他js文件能引用相關的變量和函數,返回一個全局對象供其他js文件引用。

var part1 = (function(){

    var obj1={};
    var tag=true;
    var name='a';

    function add(a,b)
    {
        return a+b;
    }
    console.log('我是a');

    obj1.tag=tag;
    obj1.add=add;

    return obj1;
})()

part2.js

var part2=(function(){
    var obj2={};
    var tag=false;
    var name='b';
    console.log('我是b');
    obj2.tag=tag;
    obj2.name=name;
    return obj2;
})()

part3.js

在引用時,通過對象引用相關的變量和函數。

if(part1.tag)
{
    console.log('我使用了part1中的tag');
}
console.log(part1.add(10,20))

結果如下:part1和part2成了兩個互不影響的模塊,如果要引用part1或者part2中的變量和函數,可以通過返回對象來引用。

ES6模塊化

 通過匿名函數加返回值的方式實現模塊化是比較繁瑣的,es6中已經幫我們實現了模塊化。

在引用js文件的時候,通過添加type="modual"屬性,各個js文件實現獨立,通過export和import,各js文件實現交互。

具體如下:

三個文件都作爲模塊引入,加入了type="modual"

<body>
<script src="../js/part1.js" type="module"></script>
<script src="../js/part2.js" type="module"></script>
<script src="../js/part3.js" type="module"></script>
</body>

part1.js

爲了讓其他js文件引用相關的變量和函數,需要將相關的變量和函數導出export{tag,add},這裏採用的是es6的語法,省略了key值。

var tag=true;
    var name='a';

    function add(a,b)
    {
        return a+b;
    }
    console.log('我是a');

    export{
        tag,add
    }

part2.js

part2暫時不需要輸出變量和函數

    var tag=false;
    var name='b';
    console.log('我是b');
    function mul(a,b)
    {
        return a*b
    }

part3.js

引用的時候通過import語法,import {tag,add} from './part1.js',tag和add分別對應export中的變量或者函數的名稱,part1.js是指定引用哪個文件中的export。

import {tag,add} from './part1.js'

if(tag)
{
    console.log('我使用了part1中的tag');
}
console.log(add(10,20))

結果如下:

export可以將所有需要輸出的變量和函數寫在一起,以對象的形式返回。也可以在定義的時候指定export。例如:將part2.js中的name變量和mul函數輸出。

part2.js修改如下:在函數前面添加export關鍵字,變量的導出也是類似的。

    var tag=false;
    export var name='b';
    console.log('我是b');
    export function mul(a,b)
    {
        return a*b;
    }

 在part3.js中引用該函數:

import {tag,add} from './part1.js'
if(tag)
{
    console.log('我使用了part1中的tag');
}
console.log(add(10,20));

import {name,mul} from './part2.js'
console.log(mul(10,20));

結果如下:

 在export和import的時候,變量或者函數的名稱必須一致,否則就找不到了。如果想在import的時候,重新給變量取個名字,需要用到export default。但是default無論是變量還是函數,只能有一個。

part2.js修改如下:輸出了一個default sex

    var tag=false;
    export var name='b';
    console.log('我是b');
    export function mul(a,b)
    {
        return a*b;
    }
    const sex='男';
    export default sex;

part3.js

給sex重新取一個名稱s

import {tag,add} from './part1.js'
if(tag)
{
    console.log('我使用了part1中的tag');
}
console.log(add(10,20));

import {name,mul} from './part2.js'
console.log(mul(10,20));

import s from './part2.js'
console.log('性別是:'+s);

結果如下:

如果需要引用的變量特別多,一個一個寫會比較長,影響美觀,可以通過對象的形式引入:

import * as obj from "./xxx.js",通過obj引用其中的變量和函數。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章