table 模塊是我們的又一走心之作,在 layui 2.0 的版本中全新推出,是 layui 最核心的組成之一。它用于對表格進(jìn)行一些列功能和動態(tài)化數(shù)據(jù)操作,涵蓋了日常業(yè)務(wù)所涉及的幾乎全部需求。支持固定表頭、固定行、固定列左/列右,支持拖拽改變列寬度,支持排序,支持多級表頭,支持單元格的自定義模板,支持對表格重載(比如搜索、條件篩選等),支持復(fù)選框,支持分頁,支持單元格編輯等等一些列功能。盡管如此,我們?nèi)詫ζ溥M(jìn)行完善,在控制代碼量和性能的前提下,不定期增加更多人性化功能。table 模塊也將是 layui 重點維護(hù)的項目之一。
模塊加載名稱:table
創(chuàng)建一個table實例最簡單的方式是,在頁面放置一個元素 <table id="demo"></table>,然后通過 table.render() 方法指定該容器,如下所示:
上面你已經(jīng)看到了一個簡單數(shù)據(jù)表格的基本樣子,你一定迫不及待地想知道它的使用方式。下面就是它對應(yīng)的代碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>table模塊快速使用</title> <link rel="stylesheet" href="/layui/css/layui.css" media="all"> </head> <body> <table id="demo" lay-filter="test"></table> <script src="/layui/layui.js"></script> <script> layui.use('table', function(){ var table = layui.table; //第一個實例 table.render({ elem: '#demo' ,height: 312 ,url: '/doc/layui/demo/table/user.json' //數(shù)據(jù)接口 ,page: true //開啟分頁 ,cols: [[ //表頭 {field: 'id', title: 'ID', width:80, sort: true, fixed: 'left'} ,{field: 'username', title: '用戶名', width:80} ,{field: 'sex', title: '性別', width:80, sort: true} ,{field: 'city', title: '城市', width:80} ,{field: 'sign', title: '簽名', width: 177} ,{field: 'experience', title: '積分', width: 80, sort: true} ,{field: 'score', title: '評分', width: 80, sort: true} ,{field: 'classify', title: '職業(yè)', width: 80} ,{field: 'wealth', title: '財富', width: 135, sort: true} ]] }); }); </script> </body> </html>
一切都并不會陌生:綁定容器、設(shè)置數(shù)據(jù)接口、在表頭設(shè)定對應(yīng)的字段,剩下的…就交給 layui 吧。你的牛刀是否早已饑渴難耐?那么不妨現(xiàn)在就去小試一波吧。數(shù)據(jù)接口可參考:返回的數(shù)據(jù),規(guī)則在下文也有講解。
在上述“快速使用”的介紹中,你已經(jīng)初步見證了 table 模塊的信手拈來,但其使用方式并不止那一種。我們?yōu)榱藵M足各種情況下的需求,對 table 模塊做了三種初始化的支持,你可按照個人喜好和實際情況靈活使用。
方式 | 機制 | 適用場景 | |
---|---|---|---|
01. | 方法渲染 | 用JS方法的配置完成渲染 | (推薦)無需寫過多的 HTML,在 JS 中指定原始元素,再設(shè)定各項參數(shù)即可。 |
02. | 自動渲染 | HTML配置,自動渲染 | 無需寫過多 JS,可專注于 HTML 表頭部分 |
03. | 轉(zhuǎn)換靜態(tài)表格 | 轉(zhuǎn)化一段已有的表格元素 | 無需配置數(shù)據(jù)接口,在JS中指定表格元素,并簡單地給表頭加上自定義屬性即可 |
其實這是“自動化渲染”的手動模式,本質(zhì)類似,只是“方法級渲染”將基礎(chǔ)參數(shù)的設(shè)定放在了JS代碼中,且原始的 table 標(biāo)簽只需要一個 選擇器:
<table id="demo" lay-filter="test"></table>
var table = layui.table; //執(zhí)行渲染 table.render({ elem: '#demo' //指定原始表格元素選擇器(推薦id選擇器) ,height: 315 //容器高度 ,cols: [{}] //設(shè)置表頭 //,…… //更多參數(shù)參考右側(cè)目錄:基本參數(shù)選項 });
事實上我們更推薦采用“方法級渲染”的做法,其最大的優(yōu)勢在于你可以脫離HTML文件,而專注于JS本身。尤其對于項目的頻繁改動及發(fā)布,其便捷性會體現(xiàn)得更為明顯。而究竟它與“自動化渲染”的方式誰更簡單,也只能由各位猿猿們自行體味了。
備注:table.render()方法返回一個對象:var tableIns = table.render(options),可用于對當(dāng)前表格進(jìn)行“重載”等操作,詳見目錄:表格重載
所謂的自動渲染,即:在一段 table 容器中配置好相應(yīng)的參數(shù),由 table 模塊內(nèi)部自動對其完成渲染,而無需你寫初始的渲染方法。其特點在上文也有闡述。你需要關(guān)注的是以下三點:
1) 帶有 class="layui-table" 的 <table> 標(biāo)簽。
2) 對標(biāo)簽設(shè)置屬性 lay-data="" 用于配置一些基礎(chǔ)參數(shù)
3) 在 <th> 標(biāo)簽中設(shè)置屬性lay-data=""用于配置表頭信息
按照上述的規(guī)范寫好table原始容器后,只要你加載了layui 的 table 模塊,就會自動對其建立動態(tài)的數(shù)據(jù)表格。下面是一個示例:
<table class="layui-table" lay-data="{height:315, url:'/doc/layui/demo/table/user.json', page:true, id:'test'}" lay-filter="test"> <thead> <tr> <th lay-data="{field:'id', width:80, sort: true}">ID</th> <th lay-data="{field:'username', width:80}">用戶名</th> <th lay-data="{field:'sex', width:80, sort: true}">性別</th> <th lay-data="{field:'city'}">城市</th> <th lay-data="{field:'sign'}">簽名</th> <th lay-data="{field:'experience', sort: true}">積分</th> <th lay-data="{field:'score', sort: true}">評分</th> <th lay-data="{field:'classify'}">職業(yè)</th> <th lay-data="{field:'wealth', sort: true}">財富</th> </tr> </thead> </table>
假設(shè)你的頁面已經(jīng)存在了一段有內(nèi)容的表格,它由原始的table標(biāo)簽組成,這時你需要賦予它一些動態(tài)元素,比如拖拽調(diào)整列寬?比如排序等等?那么你同樣可以很輕松地去實現(xiàn)。如下所示:
昵稱 | 積分 | 簽名 |
---|---|---|
賢心1 | 66 | 人生就像是一場修行a |
賢心2 | 88 | 人生就像是一場修行b |
賢心3 | 33 | 人生就像是一場修行c |
通過上面的小例子,你已經(jīng)初步見識了這一功能的實際意義。嘗試在你的靜態(tài)表格的 th 標(biāo)簽中加上 lay-data="" 屬性,代碼如下:
<table lay-filter="demo"> <thead> <tr> <th lay-data="{field:'username', width:100}">昵稱</th> <th lay-data="{field:'experience', width:80, sort:true}">積分</th> <th lay-data="{field:'sign'}">簽名</th> </tr> </thead> <tbody> <tr> <td>賢心1</td> <td>66</td> <td>人生就像是一場修行a</td> </tr> <tr> <td>賢心2</td> <td>88</td> <td>人生就像是一場修行b</td> </tr> <tr> <td>賢心3</td> <td>33</td> <td>人生就像是一場修行c</td> </tr> </tbody> </table>
然后執(zhí)行用于轉(zhuǎn)換表格的JS方法,就可以達(dá)到目的了:
var table = layui.table;
//轉(zhuǎn)換靜態(tài)表格
table.init('demo', {
height: 315 //設(shè)置高度
,limit: 10 //注意:請務(wù)必確保 limit 參數(shù)(默認(rèn):10)是與你服務(wù)端限定的數(shù)據(jù)條數(shù)一致
//支持所有基礎(chǔ)參數(shù)
});
在前面的“方法渲染”和“自動渲染”兩種方式中,你的數(shù)據(jù)都來源于異步的接口,這可能并不利于所謂的seo(當(dāng)然是針對于前臺頁面)。而在這里,你的數(shù)據(jù)已和頁面同步輸出,卻仍然可以轉(zhuǎn)換成動態(tài)表格,是否感受到一絲愜意呢?
基礎(chǔ)參數(shù)并非所有都要出現(xiàn),有必選也有可選,結(jié)合你的實際需求自由設(shè)定?;A(chǔ)參數(shù)一般出現(xiàn)在以下幾種場景中:
場景一:下述方法中的鍵值即為基礎(chǔ)參數(shù)項 table.render({ height: 300 ,url: '/api/data' }); 場景二:下述 lay-data 里面的內(nèi)容即為基礎(chǔ)參數(shù)項,切記:值要用單引號 <table lay-data="{height:300, url:'/api/data'}" lay-filter="demo"> …… </table> 更多場景:下述 options 即為含有基礎(chǔ)參數(shù)項的對象 > table.init('filter', options); //轉(zhuǎn)化靜態(tài)表格 > var tableObj = table.render({}); tableObj.reload(options); //重載表格
下面是目前 table 模塊所支持的全部參數(shù)一覽表,我們對重點參數(shù)進(jìn)行了的詳細(xì)說明,你可以點擊下述表格最右側(cè)的“示例”去查看
參數(shù) | 類型 | 說明 | 示例值 |
---|---|---|---|
elem | String/DOM | 指定原始 table 容器的選擇器或 DOM,方法渲染方式必填 | "#demo" |
cols | Array | 設(shè)置表頭。值是一個二維數(shù)組。方法渲染方式必填 | 詳見表頭參數(shù) |
url(等) | - | 異步數(shù)據(jù)接口相關(guān)參數(shù)。其中 url 參數(shù)為必填項 | 詳見異步參數(shù) |
toolbar | String/DOM/Boolean |
開啟表格頭部工具欄區(qū)域,該參數(shù)支持四種類型值:
注意:
1. 該參數(shù)為 layui 2.4.0 開始新增。 2. 若需要“列顯示隱藏”、“導(dǎo)出”、“打印”等功能,則必須開啟該參數(shù) |
false |
defaultToolbar | Array | 該參數(shù)可自由配置頭部工具欄右側(cè)的圖標(biāo)按鈕 | 詳見頭工具欄圖標(biāo) |
width | Number | 設(shè)定容器寬度。table容器的默認(rèn)寬度是跟隨它的父元素鋪滿,你也可以設(shè)定一個固定值,當(dāng)容器中的內(nèi)容超出了該寬度時,會自動出現(xiàn)橫向滾動條。 | 1000 |
height | Number/String | 設(shè)定容器高度 | 詳見height |
cellMinWidth | Number | (layui 2.2.1 新增)全局定義所有常規(guī)單元格的最小寬度(默認(rèn):60),一般用于列寬自動分配的情況。其優(yōu)先級低于表頭參數(shù)中的 minWidth | 100 |
done | Function | 數(shù)據(jù)渲染完的回調(diào)。你可以借此做一些其它的操作 | 詳見 done 回調(diào) |
error | Function |
數(shù)據(jù)請求失敗的回調(diào),返回兩個參數(shù):錯誤對象、內(nèi)容
layui 2.6.0 新增 |
- |
data | Array | 直接賦值數(shù)據(jù)。既適用于只展示一頁數(shù)據(jù),也非常適用于對一段已知數(shù)據(jù)進(jìn)行多頁展示。 | [{}, {}, {}, {}, …] |
escape | Boolean | 是否開啟 xss 字符過濾(默認(rèn) false)layui 2.6.8 新增 | true |
totalRow | Boolean/String | 是否開啟合計行區(qū)域 | false |
page | Boolean/Object | 開啟分頁(默認(rèn):false)。支持傳入一個對象,里面可包含 laypage 組件所有支持的參數(shù)(jump、elem除外) | {theme: '#c00'} |
limit | Number |
每頁顯示的條數(shù)(默認(rèn) 10)。值需對應(yīng) limits 參數(shù)的選項。
注意:優(yōu)先級低于 page 參數(shù)中的 limit 參數(shù) |
30 |
limits | Array |
每頁條數(shù)的選擇項,默認(rèn):[10,20,30,40,50,60,70,80,90]。
注意:優(yōu)先級低于 page 參數(shù)中的 limits 參數(shù) |
[30,60,90] |
loading | Boolean | 是否顯示加載條(默認(rèn) true)。若為 false,則在切換分頁時,不會出現(xiàn)加載條。該參數(shù)只適用于 url 參數(shù)開啟的方式 | false |
title | String | 定義 table 的大標(biāo)題(在文件導(dǎo)出等地方會用到) | "用戶表" |
text | Object | 自定義文本,如空數(shù)據(jù)時的異常提示等。 | 詳見自定義文本 |
autoSort | Boolean |
默認(rèn) true,即直接由 table 組件在前端自動處理排序。
若為 false,則需自主排序,即由服務(wù)端返回排序好的數(shù)據(jù) |
詳見事件排序 |
initSort | Object |
初始排序狀態(tài)。 用于在數(shù)據(jù)表格渲染完畢時,默認(rèn)按某個字段排序。 |
詳見初始排序 |
id | String |
設(shè)定容器唯一 id。id 是對表格的數(shù)據(jù)操作方法上是必要的傳遞條件,它是表格容器的索引,你在下文諸多地方都將會見識它的存在。
另外,若該參數(shù)未設(shè)置,則默認(rèn)從 <table id="test"></table> 中的 id 屬性值中獲取。 |
test |
skin(等) | - | 設(shè)定表格各種外觀、尺寸等 | 詳見表格風(fēng)格 |
相信我,在你還尚無法駕馭 layui table 的時候,你的所有焦點都應(yīng)放在這里,它帶引領(lǐng)你完成許多可見和不可見甚至你無法想象的工作。如果你采用的是方法渲染,cols 是一個二維數(shù)組,表頭參數(shù)設(shè)定在數(shù)組內(nèi);如果你采用的自動渲染,表頭參數(shù)的設(shè)定應(yīng)放在 <th> 標(biāo)簽上
參數(shù) | 類型 | 說明 | 示例值 |
---|---|---|---|
field | String | 設(shè)定字段名。非常重要,且是表格數(shù)據(jù)列的唯一標(biāo)識 | username |
title | String | 設(shè)定標(biāo)題名稱 | 用戶名 |
width | Number/String |
設(shè)定列寬,若不填寫,則自動分配;若填寫,則支持值為:數(shù)字、百分比。
請結(jié)合實際情況,對不同列做不同設(shè)定。 |
200 30% |
minWidth | Number | 局部定義當(dāng)前常規(guī)單元格的最小寬度(默認(rèn):60),一般用于列寬自動分配的情況。其優(yōu)先級高于基礎(chǔ)參數(shù)中的 cellMinWidth | 100 |
type | String |
設(shè)定列類型??蛇x值有:
|
任意一個可選值 |
LAY_CHECKED | Boolean | 是否全選狀態(tài)(默認(rèn):false)。必須復(fù)選框列開啟后才有效,如果設(shè)置 true,則表示復(fù)選框默認(rèn)全部選中。 | true |
fixed | String | 固定列??蛇x值有:left(固定在左)、right(固定在右)。一旦設(shè)定,對應(yīng)的列將會被固定在左或右,不隨滾動條而滾動。
注意: 如果是固定在左,該列必須放在表頭最前面;如果是固定在右,該列必須放在表頭最后面。 |
left(同 true) right |
hide | Boolean | 是否初始隱藏列,默認(rèn):false。layui 2.4.0 新增 | true |
totalRow | Boolean/String |
{ "code": 0, "totalRow": { "score": "666" ,"experience": "999" }, "data": [{}, {}], "msg": "", "count": 1000 }
如上,在 totalRow 中返回所需統(tǒng)計的列字段名和值即可。
totalRow: '{{ d.TOTAL_NUMS }} 單位' //還比如只取整:'{{ parseInt(d.TOTAL_NUMS) }}' |
true |
totalRowText | String | 用于顯示自定義的合計文本。layui 2.4.0 新增 | "合計:" |
sort | Boolean |
是否允許排序(默認(rèn):false)。如果設(shè)置 true,則在對應(yīng)的表頭顯示排序icon,從而對列開啟排序功能。
注意:不推薦對值同時存在“數(shù)字和普通字符”的列開啟排序,因為會進(jìn)入字典序比對。比如:'賢心' > '2' > '100',這可能并不是你想要的結(jié)果,但字典序排列算法(ASCII碼比對)就是如此。 |
true |
unresize | Boolean | 是否禁用拖拽列寬(默認(rèn):false)。默認(rèn)情況下會根據(jù)列類型(type)來決定是否禁用,如復(fù)選框列,會自動禁用。而其它普通列,默認(rèn)允許拖拽列寬,當(dāng)然你也可以設(shè)置 true 來禁用該功能。 | false |
edit | String | 單元格編輯類型(默認(rèn)不開啟)目前只支持:text(輸入框) | text |
event | String | 自定義單元格點擊事件名,以便在 tool 事件中完成對該單元格的業(yè)務(wù)處理 | 任意字符 |
style | String | 自定義單元格樣式。即傳入 CSS 樣式 | background-color: #5FB878; color: #fff; |
align | String | 單元格排列方式??蛇x值有:left(默認(rèn))、center(居中)、right(居右) | center |
colspan | Number | 單元格所占列數(shù)(默認(rèn):1)。一般用于多級表頭 | 3 |
rowspan | Number | 單元格所占行數(shù)(默認(rèn):1)。一般用于多級表頭 | 2 |
templet | String | 自定義列模板,模板遵循 laytpl 語法。這是一個非常實用的功能,你可借助它實現(xiàn)邏輯處理,以及將原始數(shù)據(jù)轉(zhuǎn)化成其它格式,如時間戳轉(zhuǎn)化為日期字符等 | 詳見自定義模板 |
toolbar | String | 綁定工具條模板??稍诿啃袑?yīng)的列中出現(xiàn)一些自定義的操作性按鈕 | 詳見行工具事件 |
下面是一些方法渲染和自動渲染的配置方式:
//方法渲染: table.render({ cols: [[ //標(biāo)題欄 {checkbox: true} ,{field: 'id', title: 'ID', width: 80} ,{field: 'username', title: '用戶名', width: 120} ]] }); 它等價于自動渲染: <table class="layui-table" lay-data="{基礎(chǔ)參數(shù)}" lay-filter="test"> <thead> <tr> <th lay-data="{checkbox:true}"></th> <th lay-data="{field:'id', width:80}">ID</th> <th lay-data="{field:'username', width:180}">用戶名</th> </tr> </thead> </table>
以下是一個二級表頭的例子:
JS: table.render({ cols: [[ //標(biāo)題欄 {field: 'username', title: '聯(lián)系人', width: 80, rowspan: 2} //rowspan即縱向跨越的單元格數(shù) ,{field: 'amount', title: '金額', width: 80, rowspan: 2} ,{align: 'center', title: '地址', colspan: 3} //colspan即橫跨的單元格數(shù),這種情況下不用設(shè)置field和width ], [ {field: 'province', title: '省', width: 80} ,{field: 'city', title: '市', width: 120} ,{field: 'county', title: '詳細(xì)', width: 300} ]] }); 它等價于: <table class="layui-table" lay-data="{基礎(chǔ)參數(shù)}"> <thead> <tr> <th lay-data="{field:'username', width:80}" rowspan="2">聯(lián)系人</th> <th lay-data="{field:'amount', width:120}" rowspan="2">金額</th> <th lay-data="{align:'center'}" colspan="3">地址</th> </tr> <tr> <th lay-data="{field:'province', width:80}">省</th> <th lay-data="{field:'city', width:120}">市</th> <th lay-data="{field:'county', width:300}">詳細(xì)</th> </tr> </thead> </table>
需要說明的是,table 組件支持無限極表頭,你可按照上述的方式繼續(xù)擴(kuò)充。核心點在于 rowspan 和 colspan 兩個參數(shù)的使用。
類型:String,默認(rèn)值:無
在默認(rèn)情況下,單元格的內(nèi)容是完全按照數(shù)據(jù)接口返回的content原樣輸出的,如果你想對某列的單元格添加鏈接等其它元素,你可以借助該參數(shù)來輕松實現(xiàn)。這是一個非常實用且強大的功能,你的表格內(nèi)容會因此而豐富多樣。
templet 提供了三種使用方式,請結(jié)合實際場景選擇最合適的一種:
- 如果自定義模版的字符量太大,我們推薦你采用【方式一】;
- 如果自定義模板的字符量適中,或者想更方便地調(diào)用外部方法,我們推薦你采用【方式二】;
- 如果自定義模板的字符量很小,我們推薦你采用【方式三】
方式一:綁定模版選擇器。
table.render({ cols: [[ {field:'title', title: '文章標(biāo)題', width: 200, templet: '#titleTpl'} //這里的templet值是模板元素的選擇器 ,{field:'id', title:'ID', width:100} ]] }); 等價于: <th lay-data="{field:'title', width: 200, templet: '#titleTpl'}">文章標(biāo)題</th> <th lay-data="{field:'id', width:100}">ID</th>
下述是templet對應(yīng)的模板,它可以存放在頁面的任意位置。模板遵循于 laytpl 語法,可讀取到返回的所有數(shù)據(jù)
<script type="text/html" id="titleTpl">
<a href="/detail/{{d.id}}" class="layui-table-link">{{d.title}}</a>
</script>
注意:上述的 {{d.id}}、{{d.title}} 是動態(tài)內(nèi)容,它對應(yīng)數(shù)據(jù)接口返回的字段名。除此之外,你還可以讀取到以下額外字段:
序號:{{ d.LAY_INDEX }}
當(dāng)前列的表頭信息:{{ d.LAY_COL }} (layui 2.6.8 新增)
由于模板遵循 laytpl 語法(建議細(xì)讀 laytpl文檔 ),因此在模板中你可以寫任意腳本語句(如 if else/for等):
<script type="text/html" id="titleTpl">
{{# if(d.id < 100){ }}
<a href="/detail/{{d.id}}" class="layui-table-link">{{d.title}}</a>
{{# } else { }}
{{d.title}}(普通用戶)
{{# } }}
</script>
方式二:函數(shù)轉(zhuǎn)義。templet 若未函數(shù),則返回一個參數(shù) d(包含當(dāng)前行數(shù)據(jù)及特定的額外字段)。如下所示:
table.render({ cols: [[ {field:'title', title: '文章標(biāo)題', width: 200 ,templet: function(d){ console.log(d.LAY_INDEX); //得到序號。一般不常用 console.log(d.LAY_COL); //得到當(dāng)前列表頭配置信息(layui 2.6.8 新增)。一般不常用 //得到當(dāng)前行數(shù)據(jù),并拼接成自定義模板 return 'ID:'+ d.id +',標(biāo)題:<span style="color: #c00;">'+ d.title +'</span>' } } ,{field:'id', title:'ID', width:100} ]] });
方式三:直接賦值模版字符。事實上,templet 也可以直接是一段 html 內(nèi)容,如:
templet: '<div><a href="/detail/{{d.id}}" class="layui-table-link">{{d.title}}</a></div>' 注意:這里一定要被一層 <div></div> 包裹,否則無法讀取到模板
類型:String,默認(rèn)值:無
通常你需要在表格的每一行加上 查看、編輯、刪除 這樣類似的操作按鈕,而 tool 參數(shù)就是為此而生,你因此可以非常便捷地實現(xiàn)各種操作功能。tool 參數(shù)和 templet 參數(shù)的使用方式完全類似,通常接受的是一個選擇器,也可以是一段HTML字符。
table.render({ cols: [[ {field:'id', title:'ID', width:100} ,{fixed: 'right', width:150, align:'center', toolbar: '#barDemo'} //這里的toolbar值是模板元素的選擇器 ]] }); 等價于: <th lay-data="{field:'id', width:100}">ID</th> <th lay-data="{fixed: 'right', width:150, align:'center', toolbar: '#barDemo'}"></th>
下述是 toolbar 對應(yīng)的模板,它可以存放在頁面的任意位置:
<script type="text/html" id="barDemo"> <a class="layui-btn layui-btn-xs" lay-event="detail">查看</a> <a class="layui-btn layui-btn-xs" lay-event="edit">編輯</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a> <!-- 這里同樣支持 laytpl 語法,如: --> {{# if(d.auth > 2){ }} <a class="layui-btn layui-btn-xs" lay-event="check">審核</a> {{# } }} </script> 注意:屬性 lay-event="" 是模板的關(guān)鍵所在,值可隨意定義。
接下來我們可以借助 table模塊的工具條事件,完成不同的操作功能:
//工具條事件 table.on('tool(test)', function(obj){ //注:tool 是工具條事件名,test 是 table 原始容器的屬性 lay-filter="對應(yīng)的值" var data = obj.data; //獲得當(dāng)前行數(shù)據(jù) var layEvent = obj.event; //獲得 lay-event 對應(yīng)的值(也可以是表頭的 event 參數(shù)對應(yīng)的值) var tr = obj.tr; //獲得當(dāng)前行 tr 的 DOM 對象(如果有的話) if(layEvent === 'detail'){ //查看 //do somehing } else if(layEvent === 'del'){ //刪除 layer.confirm('真的刪除行么', function(index){ obj.del(); //刪除對應(yīng)行(tr)的DOM結(jié)構(gòu),并更新緩存 layer.close(index); //向服務(wù)端發(fā)送刪除指令 }); } else if(layEvent === 'edit'){ //編輯 //do something //同步更新緩存對應(yīng)的值 obj.update({ username: '123' ,title: 'xxx' }); } else if(layEvent === 'LAYTABLE_TIPS'){ layer.alert('Hi,頭部工具欄擴(kuò)展的右側(cè)圖標(biāo)。'); } });
數(shù)據(jù)的異步請求由以下幾個參數(shù)組成:
參數(shù)名 | 功能 | ||
---|---|---|---|
url |
接口地址。默認(rèn)會自動傳遞兩個參數(shù):?page=1&limit=30(該參數(shù)可通過 request 自定義)
page 代表當(dāng)前頁碼、limit 代表每頁數(shù)據(jù)量 |
||
method | 接口http請求類型,默認(rèn):get | ||
where | 接口的其它參數(shù)。如:where: {token: 'sasasas', id: 123} | ||
contentType | 發(fā)送到服務(wù)端的內(nèi)容編碼類型。如果你要發(fā)送 json 內(nèi)容,可以設(shè)置:contentType: 'application/json' | ||
headers | 接口的請求頭。如:headers: {token: 'sasasas'} | ||
parseData |
數(shù)據(jù)格式解析的回調(diào)函數(shù),用于將返回的任意數(shù)據(jù)格式解析成 table 組件規(guī)定的數(shù)據(jù)格式。 table 組件默認(rèn)規(guī)定的數(shù)據(jù)格式為(參考:/doc/layui/demo/table/user.json): { "code": 0, "msg": "", "count": 1000, "data": [{}, {}] } 很多時候,您接口返回的數(shù)據(jù)格式并不一定都符合 table 默認(rèn)規(guī)定的格式,比如: { "status": 0, "message": "", "total": 180, "data": { "item": [{}, {}] } } 那么你需要借助 parseData 回調(diào)函數(shù)將其解析成 table 組件所規(guī)定的數(shù)據(jù)格式 table.render({ elem: '#demp' ,url: '' ,parseData: function(res){ //res 即為原始返回的數(shù)據(jù) return { "code": res.status, //解析接口狀態(tài) "msg": res.message, //解析提示文本 "count": res.total, //解析數(shù)據(jù)長度 "data": res.data.item //解析數(shù)據(jù)列表 }; } //,…… //其他參數(shù) }); 該參數(shù)非常實用,系 layui 2.4.0 開始新增 |
||
request |
用于對分頁請求的參數(shù):page、limit重新設(shè)定名稱,如:
table.render({ elem: '#demp' ,url: '' ,request: { pageName: 'curr' //頁碼的參數(shù)名稱,默認(rèn):page ,limitName: 'nums' //每頁數(shù)據(jù)量的參數(shù)名,默認(rèn):limit } //,…… //其他參數(shù) });那么請求數(shù)據(jù)時的參數(shù)將會變?yōu)椋? ?curr=1&nums=30 |
||
response |
您還可以借助 response 參數(shù)來重新設(shè)定返回的數(shù)據(jù)格式,如: table.render({ elem: '#demp' ,url: '' ,response: { statusName: 'status' //規(guī)定數(shù)據(jù)狀態(tài)的字段名稱,默認(rèn):code ,statusCode: 200 //規(guī)定成功的狀態(tài)碼,默認(rèn):0 ,msgName: 'hint' //規(guī)定狀態(tài)信息的字段名稱,默認(rèn):msg ,countName: 'total' //規(guī)定數(shù)據(jù)總數(shù)的字段名稱,默認(rèn):count ,dataName: 'rows' //規(guī)定數(shù)據(jù)列表的字段名稱,默認(rèn):data } //,…… //其他參數(shù) });那么上面所規(guī)定的格式為: { "status": 200, "hint": "", "total": 1000, "rows": [] } |
注意:request 和 response 參數(shù)均為 layui 2.1.0 版本新增
調(diào)用示例:
//“方法級渲染”配置方式 table.render({ //其它參數(shù)在此省略 url: '/api/data/' //where: {token: 'sasasas', id: 123} //如果無需傳遞額外參數(shù),可不加該參數(shù) //method: 'post' //如果無需自定義HTTP類型,可不加該參數(shù) //request: {} //如果無需自定義請求參數(shù),可不加該參數(shù) //response: {} //如果無需自定義數(shù)據(jù)響應(yīng)名稱,可不加該參數(shù) }); 等價于(“自動化渲染”配置方式) <table class="layui-table" lay-data="{url:'/api/data/'}" lay-filter="test"> …… </table>
類型:Function,默認(rèn)值:無
無論是異步請求數(shù)據(jù),還是直接賦值數(shù)據(jù),都會觸發(fā)該回調(diào)。你可以利用該回調(diào)做一些表格以外元素的渲染。
table.render({ //其它參數(shù)在此省略 done: function(res, curr, count){ //如果是異步請求數(shù)據(jù)方式,res即為你接口返回的信息。 //如果是直接賦值的方式,res即為:{data: [], count: 99} data為當(dāng)前頁數(shù)據(jù)、count為數(shù)據(jù)總長度 console.log(res); //得到當(dāng)前頁碼 console.log(curr); //得到數(shù)據(jù)總量 console.log(count); } });
類型:Array,默認(rèn)值:["filter","exports","print"]
可根據(jù)值的順序顯示排版圖標(biāo),如:
defaultToolbar: ['filter', 'print', 'exports']
另外你還可以無限擴(kuò)展圖標(biāo)按鈕(layui 2.5.5 新增):
table.render({ //其它參數(shù)在此省略 defaultToolbar: ['filter', 'print', 'exports', { title: '提示' //標(biāo)題 ,layEvent: 'LAYTABLE_TIPS' //事件名,用于 toolbar 事件中使用 ,icon: 'layui-icon-tips' //圖標(biāo)類名 }] });
擴(kuò)展的圖標(biāo)可通過 toolbar 事件回調(diào)(詳見行工具事件),其中 layEvent 的值會在事件的回調(diào)參數(shù)中返回,以便區(qū)分不同的觸發(fā)動作。
類型:Object
table 模塊會內(nèi)置一些默認(rèn)的文本信息,如果想修改,你可以設(shè)置以下參數(shù)達(dá)到目的。
table.render({ //其它參數(shù)在此省略 text: { none: '暫無相關(guān)數(shù)據(jù)' //默認(rèn):無數(shù)據(jù)。 } });
類型:Object,默認(rèn)值:無
用于在數(shù)據(jù)表格渲染完畢時,默認(rèn)按某個字段排序。注:該參數(shù)為 layui 2.1.1 新增
//“方法級渲染”配置方式 table.render({ //其它參數(shù)在此省略 initSort: { field: 'id' //排序字段,對應(yīng) cols 設(shè)定的各字段名 ,type: 'desc' //排序方式 asc: 升序、desc: 降序、null: 默認(rèn)排序 } }); 等價于(“自動化渲染”配置方式) <table class="layui-table" lay-data="{initSort:{field:'id', type:'desc'}}" lay-filter="test"> …… </table>
類型:Number/String,可選值如下:
可選值 | 說明 | 示例 |
---|---|---|
不填寫 | 默認(rèn)情況。高度隨數(shù)據(jù)列表而適應(yīng),表格容器不會出現(xiàn)縱向滾動條 | - |
固定值 | 設(shè)定一個數(shù)字,用于定義容器高度,當(dāng)容器中的內(nèi)容超出了該高度時,會自動出現(xiàn)縱向滾動條 | height: 315 |
full-差值 |
高度將始終鋪滿,無論瀏覽器尺寸如何。這是一個特定的語法格式,其中 full 是固定的,而 差值 則是一個數(shù)值,這需要你來預(yù)估,比如:表格容器距離瀏覽器頂部和底部的距離“和”
PS:該功能為 layui 2.1.0 版本中新增 |
height: 'full-20' |
示例:
//“方法級渲染”配置方式 table.render({ //其它參數(shù)在此省略 height: 315 //固定值 }); table.render({ //其它參數(shù)在此省略 height: 'full-20' //高度最大化減去差值 }); 等價于(“自動化渲染”配置方式) <table class="layui-table" lay-data="{height:315}" lay-filter="test"> …… </table> <table class="layui-table" lay-data="{height:'full-20'}" lay-filter="test"> …… </table>
控制表格外觀的主要由以下參數(shù)組成:
參數(shù)名 | 可選值 | 備注 |
---|---|---|
skin |
line (行邊框風(fēng)格)
row (列邊框風(fēng)格) nob (無邊框風(fēng)格) |
用于設(shè)定表格風(fēng)格,若使用默認(rèn)風(fēng)格不設(shè)置該屬性即可 |
even | true/false | 若不開啟隔行背景,不設(shè)置該參數(shù)即可 |
size |
sm (小尺寸)
lg (大尺寸) |
用于設(shè)定表格尺寸,若使用默認(rèn)尺寸不設(shè)置該屬性即可 |
//“方法級渲染”配置方式 table.render({ //其它參數(shù)在此省略 skin: 'line' //行邊框風(fēng)格 ,even: true //開啟隔行背景 ,size: 'sm' //小尺寸的表格 }); 等價于(“自動化渲染”配置方式) <table class="layui-table" lay-data="{skin:'line', even:true, size:'sm'}" lay-filter="test"> …… </table>
基礎(chǔ)用法是table模塊的關(guān)鍵組成部分,目前所開放的所有方法如下:
> table.set(options); //設(shè)定全局默認(rèn)參數(shù)。options即各項基礎(chǔ)參數(shù) > table.on('event(filter)', callback); //事件。event為內(nèi)置事件名(詳見下文),filter為容器lay-filter設(shè)定的值 > table.init(filter, options); //filter為容器lay-filter設(shè)定的值,options即各項基礎(chǔ)參數(shù)。例子見:轉(zhuǎn)換靜態(tài)表格 > table.checkStatus(id); //獲取表格選中行(下文會有詳細(xì)介紹)。id 即為 id 參數(shù)對應(yīng)的值 > table.render(options); //用于表格方法級渲染,核心方法。應(yīng)該不用再過多解釋了,詳見:方法級渲染 > table.reload(id, options, deep); //表格重載 > table.resize(id); //重置表格尺寸 > table.exportFile(id, data, type); //導(dǎo)出數(shù)據(jù) > table.getData(id); //用于獲取表格當(dāng)前頁的所有行數(shù)據(jù)(layui 2.6.0 開始新增)
該方法可獲取到表格所有的選中行相關(guān)數(shù)據(jù)
語法:table.checkStatus('ID'),其中 ID 為基礎(chǔ)參數(shù) id 對應(yīng)的值(見:設(shè)定容器唯一ID),如:
【自動化渲染】 <table class="layui-table" lay-data="{id: 'idTest'}"> …… </table> 【方法渲染】 table.render({ //其它參數(shù)省略 id: 'idTest' });
var checkStatus = table.checkStatus('idTest'); //idTest 即為基礎(chǔ)參數(shù) id 對應(yīng)的值 console.log(checkStatus.data) //獲取選中行的數(shù)據(jù) console.log(checkStatus.data.length) //獲取選中行數(shù)量,可作為是否有選中行的條件 console.log(checkStatus.isAll ) //表格是否全選
該方法可重置表格尺寸和結(jié)構(gòu),其內(nèi)部完成了:固定列高度平鋪、動態(tài)分配列寬、容器滾動條寬高補丁 等操作。它一般用于特殊情況下(如“非窗口 resize”導(dǎo)致的表格父容器寬度變化而引發(fā)的列寬適配異常),以保證表格在此類特殊情況下依舊能友好展示。
語法:table.resize('ID'),其中 ID 為基礎(chǔ)參數(shù) id 對應(yīng)的值(見:設(shè)定容器唯一ID),如:
table.render({ //其它參數(shù)省略 ,elem: '#demo' //,…… //其它參數(shù) ,id: 'idTest' }); //執(zhí)行表格“尺寸結(jié)構(gòu)”的重置,一般寫在對應(yīng)的事件中 table.resize('idTest');
很多時候,你需要對表格進(jìn)行重載。比如數(shù)據(jù)全局搜索。以下方法可以幫你輕松實現(xiàn)這類需求(可任選一種)。
語法 | 說明 | 適用場景 |
table.reload(ID, options, deep) |
參數(shù) ID 即為基礎(chǔ)參數(shù)id對應(yīng)的值,見:設(shè)定容器唯一ID
參數(shù) options 即為各項基礎(chǔ)參數(shù) 參數(shù) deep:是否采用深度重載(即參數(shù)深度克隆,也就是重載時始終攜帶初始時及上一次重載時的參數(shù)),默認(rèn) false 注意:deep 參數(shù)為 layui 2.6.0 開始新增。 |
所有渲染方式 |
tableIns.reload(options, deep) |
參數(shù)同上
tableIns 可通過 var tableIns = table.render() 得到 |
僅限方法級渲染 |
請注意:如果你在 2.6.0 之前版本已經(jīng)習(xí)慣深度重載模式的,現(xiàn)在請在第三個參數(shù)中,加上 true,如:table.reload(ID, options, true); //這樣就跟 v2.5.7 及之前版本處理機制完全一樣?;蛘吣部梢韵裣旅孢@樣做://由于 2.6.0 之前的版本是采用深重載, //所以如果您之前真實采用了深重載機制,那么建議將以下代碼放入您的全局位置,從而可對老項目起到兼容作用 var tableReload = table.reload; table.reload = function(){ var args = []; layui.each(arguments, function(index, item){ args.push(item); }); args[2] === undefined && (args[2] = true); return tableReload.apply(null, args); }; //但如果你之前沒有采用深重載機制,也可以不放。不放甚至可以解決你之前因為多次 reload 而帶來的各種參數(shù)重疊問題
重載示例:
【HTML】 <table class="layui-table" lay-data="{id: 'idTest'}"> …… </table> 【JS】 table.reload('idTest', { url: '/api/table/search' ,where: {} //設(shè)定異步數(shù)據(jù)接口的額外參數(shù) //,height: 300 });
//所獲得的 tableIns 即為當(dāng)前容器的實例 var tableIns = table.render({ elem: '#id' ,cols: [] //設(shè)置表頭 ,url: '/api/data' //設(shè)置異步接口 ,id: 'idTest' }); //這里以搜索為例 tableIns.reload({ where: { //設(shè)定異步數(shù)據(jù)接口的額外參數(shù),任意設(shè) aaaaaa: 'xxx' ,bbb: 'yyy' //… } ,page: { curr: 1 //重新從第 1 頁開始 } }); //上述方法等價于 table.reload('idTest', { where: { //設(shè)定異步數(shù)據(jù)接口的額外參數(shù),任意設(shè) aaaaaa: 'xxx' ,bbb: 'yyy' //… } ,page: { curr: 1 //重新從第 1 頁開始 } }); //只重載數(shù)據(jù)
注意:這里的表格重載是指對表格重新進(jìn)行渲染,包括數(shù)據(jù)請求和基礎(chǔ)參數(shù)的讀取
盡管 table 的工具欄內(nèi)置了數(shù)據(jù)導(dǎo)出按鈕,但有時你可能需要通過方法去導(dǎo)出任意數(shù)據(jù),那么可以借助以下方法:
語法:table.exportFile(id, data, type)
var ins1 = table.render({ elem: '#demo' ,id: 'test' //,…… //其它參數(shù) }) //將上述表格示例導(dǎo)出為 csv 文件 table.exportFile(ins1.config.id, data); //data 為該實例中的任意數(shù)量的數(shù)據(jù)
事實上,該方法也可以不用依賴 table 的實例,可直接導(dǎo)出任意數(shù)據(jù):
table.exportFile(['名字','性別','年齡'], [ ['張三','男','20'], ['李四','女','18'], ['王五','女','19'] ], 'csv'); //默認(rèn)導(dǎo)出 csv,也可以為:xls
語法:table.on('event(filter)', callback);
注:event 為內(nèi)置事件名,filter 為容器 lay-filter 設(shè)定的值
目前所支持的所有事件見下文
默認(rèn)情況下,事件所觸發(fā)的是全部的table模塊容器,但如果你只想觸發(fā)某一個容器,使用事件過濾器即可。
假設(shè)原始容器為:<table class="layui-table" lay-filter="test"></table> 那么你的事件寫法如下:
//以復(fù)選框事件為例 table.on('checkbox(test)', function(obj){ console.log(obj) });
點擊頭部工具欄區(qū)域設(shè)定了屬性為 lay-event="" 的元素時觸發(fā)(該事件為 layui 2.4.0 開始新增)。如:
原始容器 <table id="demo" lay-filter="test"></table> 工具欄模板: <script type="text/html" id="toolbarDemo"> <div class="layui-btn-container"> <button class="layui-btn layui-btn-sm" lay-event="add">添加</button> <button class="layui-btn layui-btn-sm" lay-event="delete">刪除</button> <button class="layui-btn layui-btn-sm" lay-event="update">編輯</button> </div> </script> <script;> //JS 調(diào)用: table.render({ elem: '#demo' ,toolbar: '#toolbarDemo' //,…… //其他參數(shù) }); //觸發(fā)事件 table.on('toolbar(test)', function(obj){ var checkStatus = table.checkStatus(obj.config.id); switch(obj.event){ case 'add': layer.msg('添加'); break; case 'delete': layer.msg('刪除'); break; case 'update': layer.msg('編輯'); break; }; }); </script>
點擊復(fù)選框時觸發(fā),回調(diào)函數(shù)返回一個 object 參數(shù):
table.on('checkbox(test)', function(obj){ console.log(obj); //當(dāng)前行的一些常用操作集合 console.log(obj.checked); //當(dāng)前是否選中狀態(tài) console.log(obj.data); //選中行的相關(guān)數(shù)據(jù) console.log(obj.type); //如果觸發(fā)的是全選,則為:all,如果觸發(fā)的是單選,則為:one });
點擊表格單選框時觸發(fā),回調(diào)函數(shù)返回一個 object 參數(shù),攜帶的成員如下:
table.on('radio(test)', function(obj){ //test 是 table 標(biāo)簽對應(yīng)的 lay-filter 屬性 console.log(obj); //當(dāng)前行的一些常用操作集合 console.log(obj.checked); //當(dāng)前是否選中狀態(tài) console.log(obj.data); //選中行的相關(guān)數(shù)據(jù) });
單元格被編輯,且值發(fā)生改變時觸發(fā),回調(diào)函數(shù)返回一個object參數(shù),攜帶的成員如下:
table.on('edit(test)', function(obj){ //注:edit是固定事件名,test是table原始容器的屬性 lay-filter="對應(yīng)的值" console.log(obj.value); //得到修改后的值 console.log(obj.field); //當(dāng)前編輯的字段名 console.log(obj.data); //所在行的所有相關(guān)數(shù)據(jù) });
點擊或雙擊行時觸發(fā)。該事件為 layui 2.4.0 開始新增
//觸發(fā)行單擊事件 table.on('row(test)', function(obj){ console.log(obj.tr) //得到當(dāng)前行元素對象 console.log(obj.data) //得到當(dāng)前行數(shù)據(jù) //obj.del(); //刪除當(dāng)前行 //obj.update(fields) //修改當(dāng)前行數(shù)據(jù) }); //觸發(fā)行雙擊事件 table.on('rowDouble(test)', function(obj){ //obj 同上 });
具體用法見:綁定工具條
點擊表頭排序時觸發(fā),它通用在基礎(chǔ)參數(shù)中設(shè)置 autoSort: false 時使用,以完成服務(wù)端的排序,而不是默認(rèn)的前端排序。該事件的回調(diào)函數(shù)返回一個 object 參數(shù),攜帶的成員如下:
//禁用前端自動排序,以便由服務(wù)端直接返回排序好的數(shù)據(jù)
table.render({
elem: '#id'
,autoSort: false //禁用前端自動排序。注意:該參數(shù)為 layui 2.4.4 新增
//,… //其它參數(shù)省略
});
//觸發(fā)排序事件
table.on('sort(test)', function(obj){ //注:sort 是工具條事件名,test 是 table 原始容器的屬性 lay-filter="對應(yīng)的值"
console.log(obj.field); //當(dāng)前排序的字段名
console.log(obj.type); //當(dāng)前排序類型:desc(降序)、asc(升序)、null(空對象,默認(rèn)排序)
console.log(this); //當(dāng)前排序的 th 對象
//盡管我們的 table 自帶排序功能,但并沒有請求服務(wù)端。
//有些時候,你可能需要根據(jù)當(dāng)前排序的字段,重新向服務(wù)端發(fā)送請求,從而實現(xiàn)服務(wù)端排序,如:
table.reload('idTest', {
initSort: obj //記錄初始排序,如果不設(shè)的話,將無法標(biāo)記表頭的排序狀態(tài)。
,where: { //請求參數(shù)(注意:這里面的參數(shù)可任意定義,并非下面固定的格式)
field: obj.field //排序字段
,order: obj.type //排序方式
}
});
layer.msg('服務(wù)端排序。order by '+ obj.field + ' ' + obj.type);
});
table 模塊自推出以來,因某些功能的缺失,一度飽受非議,也背負(fù)了各種莫須有的鍋,然而我始終未曾放棄對它的優(yōu)化。為了迎合 layui 開箱即用的理念,我的工作并不是那么輕松。無論是從代碼,還是文檔和示例的撰寫上,我都進(jìn)行了多次調(diào)整,為的只是它能被更多人認(rèn)可。——賢心
layui - 在每一個細(xì)節(jié)中,用心與你溝通