layui 的模塊是基于 layui.js 內部實現的異步模塊加載方式,它并不遵循于AMD(沒有為什么,畢竟任性呀!),而是自己定義了一套更輕量的模塊規范。并且這種方式在經過了大量的實踐后,成為 layui 最核心的模塊加載引擎。
預先加載
開門見山,還是直接說使用比較妥當。Layui的模塊加載采用核心的 layui.use(mods, callback)方法,當你的JS 需要用到Layui模塊的時候,我們更推薦你采用預先加載,因為這樣可以避免到處寫layui.use的麻煩。你應該在最外層如此定義:
demo.jslayui.code
~~~
/*
Demo1.js
使用Layui的form和upload模塊
*/
layui.use(['form', 'upload'], function(){ //如果只加載一個模塊,可以不填數組。如:layui.use('form')
var form = layui.form //獲取form模塊
,upload = layui.upload; //獲取upload模塊
//監聽提交按鈕
form.on('submit(test)', function(data){
console.log(data);
});
//實例化一個上傳控件
upload({
url: '上傳接口url'
,success: function(data){
console.log(data);
}
})
});
~~~
按需加載(不推薦)
如果你有強迫癥,你對網站的性能有極致的要求,你并不想預先加載所需要的模塊,而是在觸發一個動作的時候,才去加載模塊,那么,這是允許的。你不用在你的JS最外層去包裹一個大大的 layui.use,你只需要:
demo.jslayui.code
/*
Demo2.js
按需加載一個Layui模塊
*/
//……
//你的各種JS代碼什么的
//……
//下面是在一個事件回調里去加載一個Layui模塊
button.addEventListener('click', function(){
layui.use('laytpl', function(laytpl){ //溫馨提示:多次調用use并不會重復加載laytpl.js,Layui內部有做模塊cache處理。
var html = laytpl('').render({});
console.log(html);
});
});
注意:如果你的 JS 中需要大量用到模塊,我們并不推薦你采用這種加載方式,因為這意味著你要寫很多 layui.use(),代碼可維護性不高。
建議還是采用:預先加載。即一個JS文件中,寫一個use即可。
模塊命名空間
layui 的模塊接口會綁定在 layui 對象下,內部由 layui.define() 方法來完成。每一個模塊都會一個特有的名字,并且無法被占用。所以你無需擔心模塊的空間被污染,除非你主動 delete layui.{模塊名}。調用模塊可通過 layui.use 方法來實現,然后再通過 layui 對象獲得模塊接口。如:
codelayui.code
layui.use(['layer', 'laypage', 'laydate'], function(){
var layer = layui.layer //獲得layer模塊
,laypage = layui.laypage //獲得laypage模塊
,laydate = layui.laydate; //獲得laydate模塊
//使用模塊
});
我們推薦你將所有的業務代碼都寫在一個大的 use 回調中,而不是將模塊接口暴露給全局,比如下面的方式我們是極不推薦的:
codelayui.code
//強烈不推薦下面的做法
var laypage, laydate;
layui.use(['laypage', 'laydate'], function(){
laypage = layui.laypage;
laydate = layui.laydate;
});
你之所以想使用上面的錯誤方式,是想其它地方使用不在執行一次 layui.use?但這種理解本身是存在問題的。因為如果一旦你的業務代碼是在模塊加載完畢之前執行,你的全局對象將獲取不到模塊接口,因此這樣用不僅不符合規范,還存在報錯風險。建議在你的 js 文件中,在最外層寫一個 layui.use 來加載所依賴的模塊,并將業務代碼寫在回調中,見:預先加載。
事實上,如果你不想采用 layui.use,你可以引入 layui.all.js 來替代 layui.js,見:非模塊化用法
擴展一個 layui 模塊
layui 官方提供的模塊有時可能還無法滿足你,或者你試圖按照layer的模塊規范來擴展一個模塊。那么你有必要認識layui.define()方法,相信你在文檔左側的“底層方法”中已有所閱讀。下面就就讓我們一起擴展一個Layui模塊吧:
第一步:確認模塊名,假設為:mymod,然后新建一個mymod.js 文件放入項目任意目錄下(注意:不用放入layui目錄)
第二步:編寫test.js 如下:
codelayui.code
/**
擴展一個test模塊
**/
layui.define(function(exports){ //提示:模塊也可以依賴其它模塊,如:layui.define('layer', callback);
var obj = {
hello: function(str){
alert('Hello '+ (str||'mymod'));
}
};
//輸出test接口
exports('mymod', obj);
});
第三步:設定擴展模塊所在的目錄,然后就可以在別的JS文件中使用了
codelayui.code
//config的設置是全局的
layui.config({
base: '/res/js/' //假設這是你存放拓展模塊的根目錄
}).extend({ //設定模塊別名
mymod: 'mymod' //如果 mymod.js 是在根目錄,也可以不用設定別名
,mod1: 'admin/mod1' //相對于上述 base 目錄的子目錄
});
//你也可以忽略 base 設定的根目錄,直接在 extend 指定路徑(主要:該功能為 layui 2.2.0 新增)
layui.extend({
mod2: '{/}http://cdn.xxx.com/lib/mod2' // {/}的意思即代表采用自有路徑,即不跟隨 base 路徑
})
//使用拓展模塊
layui.use(['mymod', 'mod1'], function(){
var mymod = layui.mymod
,mod1 = layui.mod1
,mod2 = layui.mod2;
mymod.hello('World!'); //彈出 Hello World!
});
大體上來說,layui 的模塊定義很類似 Require.js 和 Sea.js,但跟他們又有著明顯的不同,譬如在接口輸出等地方。
結語
其實關于模塊的核心,就是 layui.js 的兩個底層方法:一個用于定義模塊的 layui.define(),一個加載模塊的 layui.use()。