## [1.開始使用](https://www.easyweb.vip/doc/#/?id=_1%e5%bc%80%e5%a7%8b%e4%bd%bf%e7%94%a8)
?當前版本:`iframe v3.1.3`,?更新于2019/07/12,[【更新日志】](https://easyweb.vip/doc/log/)。
### [1.1.項目結構](https://www.easyweb.vip/doc/#/?id=_11%e9%a1%b9%e7%9b%ae%e7%bb%93%e6%9e%84)
~~~
|-assets
| |-css // 樣式
| |-images // 圖片
| |-js // javascript
| |-common.js // 公共js,主要配置layui擴展模塊位置
| |-libs // 第三方庫,echarts(圖表)、layui(ui框架)
| |-module // layui擴展模塊,版本更新只用替換此目錄
| |-theme // 主題資源
| |-admin.css // admin樣式
| |-admin.js // admin模塊
| |-index.js // index模塊
| |-contextMenu.js // 鼠標右鍵模塊
| |-printer.js // 打印模塊
| |-******** // 其他模塊,不一一列舉
|-page // html頁面
|-json // 模擬數據
|-index.html // 主頁面
~~~
> 與后端整合從index.html頁面入手,page、json可以刪除,assets整個目錄都是靜態資源。
### [1.2.導入項目](https://www.easyweb.vip/doc/#/?id=_12%e5%af%bc%e5%85%a5%e9%a1%b9%e7%9b%ae)
1. 在`我的訂單`中下載項目源碼;
2. 使用IDEA、WebStorm、HBuilder等工具打開;
3. 運行index.html啟動:

> 注意:使用`http://`的形式訪問,而不是使用`file://`的形式訪問。
### [1.3.index.html結構說明](https://www.easyweb.vip/doc/#/?id=_13indexhtml%e7%bb%93%e6%9e%84%e8%af%b4%e6%98%8e)
~~~
<html>
<head>
<link rel="stylesheet" href="assets/libs/layui/css/layui.css"/>
<link rel="stylesheet" href="assets/module/admin.css"/>
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<!-- 頭部 -->
<div class="layui-header">...</div>
<!-- 側邊欄 -->
<div class="layui-side">...</div>
<!-- 主體部分 -->
<div class="layui-body">...</div>
<!-- 底部 -->
<div class="layui-footer">...</div>
</div>
<script type="text/javascript" src="assets/libs/layui/layui.js"></script>
<script type="text/javascript" src="assets/js/common.js"></script>
<script>
layui.use(['index'], function () {
var index = layui.index;
// 加載主頁
index.loadHome({
menuPath: 'page/console/console.html',
menuName: '<i class="layui-icon layui-icon-home"></i>'
});
});
</script>
</body>
</html>
~~~
> index.html就是這樣固定的結構,在整合到后臺時,你可以把頭部、側邊欄抽離出來,再include進去。
### [1.4.添加一個菜單](https://www.easyweb.vip/doc/#/?id=_14%e6%b7%bb%e5%8a%a0%e4%b8%80%e4%b8%aa%e8%8f%9c%e5%8d%95)
1. 打開`index.html`,找到側導航欄,添加一個菜單:
~~~
<dd><a lay-href="xxx.html">XX管理</a></dd>
<!-- 還可以增加ew-title屬性自定義打開的Tab標題
<a lay-href="xxx.html" ew-title="XXXXX">XX管理</a> -->
~~~
2. 新建一個`xxx.html`頁面;
3. 運行項目,查看效果。
> 注意:a標簽里面是`lay-href`而不是`href`,lay-href點擊會打開一個Tab標簽頁。
### [1.5.common.js說明](https://www.easyweb.vip/doc/#/?id=_15commonjs%e8%af%b4%e6%98%8e)
~~~
layui.config({
base: getProjectUrl() + 'assets/module/' // 配置layui擴展模塊目錄
}).extend({ // 配置每個模塊分別所在的目錄
notice: 'notice/notice',
step: 'step-lay/step'
}).use(['admin'], function () {
var admin = layui.admin;
// 移除loading動畫
setTimeout(function () {
admin.removeLoading();
}, window == top ? 600 : 100);
});
// 獲取項目根路徑
function getProjectUrl() {
return '...省略';
}
~~~
* layui.config是告訴layui擴展模塊所在目錄;
* layui.extend是配置每個模塊具體js位置;
* admin.removeLoading()是移除頁面加載動畫;
?像`admin.js`、`index.js`這些沒有用子目錄存放的模塊不需要配置layui.extend,延時移除加載動畫是給切換主題預留時間。
> 每個頁面都需要引入common.js
* * *
## [2.index模塊](https://www.easyweb.vip/doc/#/?id=_2index%e6%a8%a1%e5%9d%97)
使用方法:
~~~
layui.use(['index'], function () {
var index = layui.index;
});
~~~
### [2.1.選項卡配置](https://www.easyweb.vip/doc/#/?id=_21%e9%80%89%e9%a1%b9%e5%8d%a1%e9%85%8d%e7%bd%ae)
| 配置名 | 默認 | 說明 |
| :-- | :-- | :-- |
| pageTabs | true | 是否開啟多標簽 |
| cacheTab | true | 是否記憶打開的選項卡 |
| openTabCtxMenu | true | 是否開啟Tab右鍵菜單 |
| maxTabNum | 20 | 最多打開多少個tab |
修改默認配置直接打開index.js修改這幾個參數即可:
~~~
var index = {
pageTabs: true, // 是否開啟多標簽
cacheTab: true, // 是否記憶打開的選項卡
openTabCtxMenu: true, // 是否開啟Tab右鍵菜單
maxTabNum: 20 // 最多打開多少個tab
// ... 省略
}
~~~
> 在設置界面修改的配置會高于index中的默認配置,設置界面的配置信息是放在緩存中,清除緩存就會以index中配置為主。
### [2.2.loadHome加載主頁](https://www.easyweb.vip/doc/#/?id=_22loadhome%e5%8a%a0%e8%bd%bd%e4%b8%bb%e9%a1%b5)
~~~
layui.use(['index'], function () {
var index = layui.index;
index.loadHome({
menuPath: 'page/console/console.html',
menuName: '<i class="layui-icon layui-icon-home"></i>'
});
});
~~~
* menuPath:?必填?主頁路徑
* menuName:?必填?Tab標題
> index.loadHome()方法在index.html中調用即可。
### [2.3.openTab打開選項卡](https://www.easyweb.vip/doc/#/?id=_23opentab%e6%89%93%e5%bc%80%e9%80%89%e9%a1%b9%e5%8d%a1)
~~~
index.openTab({
title: '百度',
url: 'https://www.baidu.com',
end: function() {
// table.reload('userTable');
}
});
~~~
* title: 選項卡的標題
* url: 打開的頁面地址
* end: Tab關閉的回調事件
?也可以直接使用`<a ew-href="xxx.html">XXX</a>`,注意是`ew-href`,還可以增加`ew-title`屬性設置Tab標題:`<a ew-href="xxx.html" ew-title="XXX管理">XXX</a>`。
> 注意:單標簽模式下end回調無效。
### [2.4.closeTab關閉選項卡](https://www.easyweb.vip/doc/#/?id=_24closetab%e5%85%b3%e9%97%ad%e9%80%89%e9%a1%b9%e5%8d%a1)
~~~
index.closeTab('https://www.baidu.com');
~~~
關閉已經打開的Tab選項卡,參數是Tab的url,單標簽模式下此方法無效。
### [2.5.clearTabCache清除Tab記憶](https://www.easyweb.vip/doc/#/?id=_25cleartabcache%e6%b8%85%e9%99%a4tab%e8%ae%b0%e5%bf%86)
~~~
index.clearTabCache();
~~~
?Tab記憶功能是刷新頁面的時候可以恢復上次打開的所有Tab,此方法用于清除已經緩存的Tab。
> 注意:在實際項目中,登錄成功后應該調用此方法清除Tab記憶。
### [2.6.setTabTitle修改Tab標題](https://www.easyweb.vip/doc/#/?id=_26settabtitle%e4%bf%ae%e6%94%b9tab%e6%a0%87%e9%a2%98)
~~~
index.setTabTitle('Hello'); // 修改當前Tab標題文字,也支持單標簽模式
index.setTabTitle(title, tabId); // 修改指定Tab標題文字
index.setTabTitleHtml('<span>Hello</span>'); // 修改整個標題欄的html,此方法只在單標簽模式有效
~~~
?關閉多標簽時框架會自動生成一個標題欄,可使用此方法修改標題欄內容,參數為undefined時為隱藏標題欄。
### [2.7.切換Tab自動刷新](https://www.easyweb.vip/doc/#/?id=_27%e5%88%87%e6%8d%a2tab%e8%87%aa%e5%8a%a8%e5%88%b7%e6%96%b0)
默認是關閉的,在設置界面可開啟,如果要直接開啟在index.html中添加如下代碼:
~~~
$('.layui-body>.layui-tab[lay-filter="admin-pagetabs"]').attr('lay-autoRefresh', 'true');
~~~
給layui-tab增加`lay-autoRefresh`屬性為true即可。
### [2.8.側邊欄手風琴折疊](https://www.easyweb.vip/doc/#/?id=_28%e4%be%a7%e8%be%b9%e6%a0%8f%e6%89%8b%e9%a3%8e%e7%90%b4%e6%8a%98%e5%8f%a0)
默認是開啟的,如要關閉配置如下:
~~~
<!-- 側邊欄 -->
<div class="layui-side">
<div class="layui-side-scroll">
<ul class="layui-nav layui-nav-tree" lay-accordion="false">
......省略其他部分
</ul>
</div>
</div>
~~~
修改`lay-accordion`屬性為false或者直接去掉即可。
* * *
## [3.admin模塊](https://www.easyweb.vip/doc/#/?id=_3admin%e6%a8%a1%e5%9d%97)
### [3.1.默認主題、存儲表名](https://www.easyweb.vip/doc/#/?id=_31%e9%bb%98%e8%ae%a4%e4%b8%bb%e9%a2%98%e3%80%81%e5%ad%98%e5%82%a8%e8%a1%a8%e5%90%8d)
修改這兩個默認的配置打開admin.js修改如下參數即可:
~~~
var admin = {
defaultTheme: 'theme-admin', // 默認主題
tableName: 'easyweb' // 存儲表名
// ...省略
}
~~~
* `defaultTheme`是默認的主題,可修改成`theme-red`等你配置的主題。
* `tableName`是本地緩存的表名,如果一個域名下有多個項目,建議修改成不同的名字。
### [3.2.全部方法](https://www.easyweb.vip/doc/#/?id=_32%e5%85%a8%e9%83%a8%e6%96%b9%e6%b3%95)
| 方法 | 參數 | 描述 |
| :-- | :-- | :-- |
| flexible(expand) | true和false | 折疊/展開側導航 |
| activeNav(url) | a標簽里面的lay-href值 | 設置側導航欄選中 |
| refresh(url) | url,可為空 | 刷新指定Tab或當前Tab |
| closeAllTabs() | 無 | 關閉所有選項卡 |
| closeOtherTabs(url) | url | 關閉除url外所有選項卡 |
| closeThisTabs(url) | url,可為空 | 關閉url或當前選項卡 |
| rollPage(d) | 方向(left、right、auto) | 滾動選項卡tab |
| iframeAuto() | 無 | 讓當前的ifram彈層自適應高度 |
| closeThisDialog() | 無 | 關閉當前iframe彈窗 |
| closeDialog(elem) | dom選擇器 | 關閉elem元素所在的彈窗(頁面層彈窗) |
| putTempData(key, value) | key,value | 緩存臨時數據 |
| getTempData(key,) | key | 獲取緩存的臨時數據 |
| parseJSON(string) | 字符串 | 解析json,解析失敗返回undefined |
| getPageHeight() | 無 | 獲取瀏覽器高度 |
| getPageWidth() | 無 | 獲取瀏覽器寬度 |
| btnLoading(elem) | dom選擇器 | 設置按鈕為加載狀態 |
| openSideAutoExpand() | 無 | 開啟鼠標移入側邊欄自動展開 |
| openCellAutoExpand() | 無 | 開啟鼠標移入表格單元格超出內容自動展開 |
| modelForm(layero, btnFilter, formFilter) | | 把彈窗自帶的按鈕跟彈窗內的表單綁定一起 |
使用示例:
~~~
layui.use(['admin'], function () {
var admin = layui.admin;
var pageHeight = admin.getPageHeight(); // 獲取瀏覽器高度
});
~~~
**按鈕loading:**
~~~
admin.btnLoading('#btn1'); // 設置按鈕為loading狀態
admin.btnLoading('#btnLoading', false); // 移除按鈕的loading狀態
admin.btnLoading('#btn1', '加載中'); // 設置按鈕為loading狀態,同時修改按鈕文字
admin.btnLoading('#btnLoading', '保存', false); // 移除按鈕的loading狀態,同時修改按鈕文字
~~~
**admin.iframeAuto()方法:**?針對type:2的彈窗自適應彈窗高度,寫在你的彈窗的子頁面中,此方法是調用一次做一次高度自適應,如果你用js動態修改了彈窗子頁面的高度,需要再調用一次。
~~~
layui.use(['admin'], function(){
var admin = layui.admin;
admin.iframeAuto();
});
~~~
**admin.closeThisDialog()關閉當前iframe類型彈窗:**?針對type:2的彈窗,在彈窗的子頁面調用即可關閉當前的iframe彈窗。
**admin.closeDialog(elem)關閉非iframe類型的彈窗:**?調用傳遞任意一個彈窗頁面里面的元素即可,比如彈窗里面有一個`<button id="xxx">`:
~~~
admin.closeDialog('#xxx'); // 即可關閉xxx元素所在的頁面層的彈窗
~~~
關閉彈窗還可以使用ew-event操作:
~~~
<!-- 關閉iframe類型的彈窗 -->
<button ew-event="closeDialog"></button>
<!-- 關閉頁面層的彈窗 -->
<button ew-event="closePageDialog"></button>
~~~
> admin.openSideAutoExpand()方法在index.html中調用,admin.openCellAutoExpand()可在任何頁面調用
### [3.3.彈窗popupRight和open](https://www.easyweb.vip/doc/#/?id=_33%e5%bc%b9%e7%aa%97popupright%e5%92%8copen)
~~~
// 打開彈窗
admin.open({
type: 2,
content: 'tpl-theme.html'
});
// 右側打開面板
admin.popupRight({
type: 2,
content: 'tpl-theme.html'
});
~~~
?這兩個方法只是對layer.open進行了一層封裝,使得彈窗可以有更好的樣式,可以跟隨主題改變顏色。
> open和popupRight參數和layer用法一樣,查看[layer文檔](https://www.layui.com/doc/modules/layer.html)。
popupRight右側面板示例:

?`type:2, content:xxx`這種是iframe類型的彈窗,也可以使用`url`,這個參數是額外增加的,使用`url`會通過ajax方式加載頁面到彈窗中,而不是iframe,看到很多人喜歡把彈窗頁面獨立,然而父子頁面傳值又比較麻煩,所以增加了url方式。
~~~
admin.open({
title: 'Hello',
url: 'tpl-theme.html'
});
admin.popupRight({
url: 'tpl-theme.html'
});
~~~
?當你使用url方式加載的時候,你的彈窗頁面應該時代碼片段,而不是完整的html,如下所示:
~~~
<form id="modelRoleForm" lay-filter="modelRoleForm" class="layui-form model-form">
<input name="roleId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">角色名</label>
<div class="layui-input-block">
<input name="roleName" placeholder="請輸入角色名" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item text-right">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="modelSubmitRole" lay-submit>保存</button>
</div>
</form>
<script>
layui.use(['layer', 'form'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
// 表單提交事件
form.on('submit(modelSubmitRole)', function (data) {
console.log(data.field);
return false;
});
});
</script>
~~~
?頁面不需要html、body這些東西,并且可以直接用`<script>`標簽來寫事件,至于參數傳遞,請查看下面的彈窗專題。
### [3.4.顯示加載動畫](https://www.easyweb.vip/doc/#/?id=_34%e6%98%be%e7%a4%ba%e5%8a%a0%e8%bd%bd%e5%8a%a8%e7%94%bb)
**`showLoading`顯示加載動畫:**
~~~
admin.showLoading('#xxx'); // 在id為xxx的元素中顯示加載層
admin.showLoading('#xxx', 1, '.8'); // 顯示type為1透明度為0.8的遮罩層
~~~
* 參數一`elem`?非必填?元素選擇器,不填為body;
* 參數二`type`?非必填?動畫類型(1 小球,2 魔方,3信號),默認是1;
* 參數三`opacity`?非必填?透明度(0 - 1),默認不透明;
?目前增加了尺寸的控制,提供有兩種尺寸,用法:
~~~
admin.showLoading({
elem: '#xxx',
type: 1,
size: 'sm'
});
~~~
?默認是sm小型尺寸,還可以選md大型尺寸
**removeLoading`移除加載動畫:**
~~~
admin.removeLoading('#xxx');
admin.removeLoading('#xxx', true, true);
~~~
* 參數一?非必填?元素選擇器,不填為body;
* 參數二?非必填?true是淡出效果,false直接隱藏,默認是true;
* 參數三?非必填?true是刪除,false是隱藏不刪除,默認是false;
**也可以寫在body中作為頁面載入的加載動畫:**
~~~
<body>
<!-- 小球樣式 -->
<div class="page-loading">
<div class="ball-loader">
<span></span><span></span><span></span><span></span>
</div>
</div>
<!-- 魔方樣式 -->
<div class="page-loading">
<div class="rubik-loader">
</div>
</div>
<!-- 信號樣式 -->
<div class="page-loading">
<div class="signal-loader">
<span></span><span></span><span></span><span></span>
</div>
</div>
<!-- 加sm是小型尺寸 -->
<div class="page-loading">
<div class="signal-loader sm">
<span></span><span></span><span></span><span></span>
</div>
</div>
</body>
~~~
?寫在頁面中需要在js中調用`admin.removeLoading()`移除加載動畫,不過common.js中已經寫了。
### [3.5.ajax封裝](https://www.easyweb.vip/doc/#/?id=_35ajax%e5%b0%81%e8%a3%85)
**`admin.req`是固定的寫法,用法如下:**
~~~
admin.req('url',{
參數一: 'xxx',
參數二: 'xxx'
}, function(res){
alert(res.code + '-' + res.msg);
}, 'get');
~~~
* 參數一?請求的url
* 參數二?請求參數
* 參數三?請求回調(失敗也進此回調,404、403等)
* 參數四?請求方式,get、post、put、delete等
**`admin.ajax`參數跟$.ajax參數一致,用法如下:**
~~~
admin.ajax({
url: 'url',
data: {},
type: 'post',
dataType: 'json',
success: function(res){
alert(res.code + '-' + res.msg);
}
});
~~~
?admin.req和admin.ajax都實現了自動傳遞header、預處理、系統錯誤依然回調到success等功能。
**自動傳遞header:**
?重寫admin的`getAjaxHeaders`方法:
~~~
admin.getAjaxHeaders = function (requestUrl) {
var headers = new Array();
headers.push({name: 'token', value: 'xxxxx'});
return headers;
}
~~~
**請求回調預處理:**
?重寫admin的`ajaxSuccessBefore`方法:
~~~
admin.ajaxSuccessBefore = function (res, requestUrl) {
if(res.code==401){
alert('登錄超時,請重新登錄');
return false; // 返回false阻止代碼執行
}
return true;
}
~~~
> 重寫的操作建議放在common.js里面,這樣就不用每個頁面都去重寫了,只要保證重寫是在調用req、ajax之前即可。
### [3.6.ew-event事件綁定](https://www.easyweb.vip/doc/#/?id=_36ew-event%e4%ba%8b%e4%bb%b6%e7%bb%91%e5%ae%9a)
使用示例:
~~~
<a ew-event="fullScreen">全屏</a>
<a ew-event="flexible">折疊導航</a>
~~~
| 事件 | 描述 |
| :-- | :-- |
| flexible | 折疊側導航 |
| refresh | 刷新主體部分 |
| closeThisTabs | 關閉當前選項卡 |
| closeOtherTabs | 關閉其他選項卡 |
| closeAllTabs | 關閉全部選項卡 |
| leftPage | 左滾動選項卡 |
| rightPage | 右滾動選項卡 |
| closeDialog | 關閉當前iframe彈窗 |
| closePageDialog | 關閉當前頁面層彈窗 |
| theme | 打開主題設置彈窗 |
| note | 打開便簽彈窗 |
| message | 打開消息彈窗 |
| psw | 打開修改密碼彈窗 |
| logout | 退出登錄 |
| fullScreen | 全屏切換 |
| back | 瀏覽器后退 |
| open | 打開彈窗 |
| popupRight | 打開右側彈窗 |
`theme`、`note`等可以通過`data-url`屬性配置對應的url,還可以通過`data-window="top"`屬性在父頁面處理事件。
~~~
<a ew-event="theme" data-url="xxx.html">主題</a>
~~~
`ew-event`屬性可用于任何元素,不僅僅是a標簽。
#### [3.6.1.open事件和popupRight](https://www.easyweb.vip/doc/#/?id=_361open%e4%ba%8b%e4%bb%b6%e5%92%8cpopupright)
?這兩個事件是用來支持非js方式打開彈窗:
~~~
<button ew-event="open" data-type="2" data-content="http://baidu.com">iframe彈窗</button>
<button ew-event="open" data-type="1" data-url="form.html">頁面彈窗</button>
<button ew-event="open" data-type="1" data-content="#userForm">頁面彈窗</button>
<form id="userForm">......省略</form>
<!-- 設置area和offset -->
<button ew-event="open" data-type="1" data-content="Hello" data-area="80px,60px" data-offset="10px,10px">頁面彈窗</button>
<!-- popupRight一樣的用法 -->
<button ew-event="popupRight" data-type="2" data-url="http://baidu.com" data-title="百度一下,你就知道">右側彈窗</button>
~~~
?layer支持的參數大部分都可以通過data屬性來設置,數組類型用逗號分隔,function類型不支持。
### [3.7.提示框](https://www.easyweb.vip/doc/#/?id=_37%e6%8f%90%e7%a4%ba%e6%a1%86)
鼠標滑過彈出tips,使用示例:
~~~
<button lay-tips="大家好!">按鈕</button>
<button lay-tips="大家好!" lay-direction="2" lay-bg="#009788">按鈕</button>
<button lay-tips="大家好!" lay-offset="10px">按鈕</button>
<button lay-tips="大家好!" lay-offset="10px,10px">按鈕</button>
~~~
* `lay-direction`: 設置位置,1上面(默認);2右邊;3下面;4 左邊;
* `lay-bg`: 設置背景顏色;
* `lay-offset`: 設置偏移距離,(上下,左右)

### [3.8.chooseLocation地圖選擇位置](https://www.easyweb.vip/doc/#/?id=_38chooselocation%e5%9c%b0%e5%9b%be%e9%80%89%e6%8b%a9%e4%bd%8d%e7%bd%ae)
~~~
admin.chooseLocation({
needCity: true,
onSelect: function (res) {
layer.msg(JSON.stringify(res), {icon: 1});
}
});
~~~
| 參數 | 默認 | 描述 |
| :-- | :-- | :-- |
| title | "選擇位置" | 彈窗標題 |
| needCity | false | 是否返回行政區,省市區默認不返回 |
| center | 定位當前城市 | 地圖默認的中心點 |
| defaultZoom | 11 | 地圖默認縮放級別 |
| pointZoom | 17 | 選中時地圖的縮放級別 |
| keywords | 無 | poi檢索關鍵字,例如:建筑、寫字樓 |
| pageSize | 30 | poi檢索最大數量 |
| onSelect | 無 | 選擇回調 |
| mapJsUrl | 內置 | 高德地圖js的url |
* 地圖默認中心點參考值:\[116.397428, 39.90923\],經度,緯度
* 地圖url參考值:`https://webapi.amap.com/maps?v=1.4.14&key=xxxxxxx`
* 返回結果說明:
* res.name; // 地點名稱
* res.address; // 詳細地址
* res.lat; // 緯度
* res.lng; // 經度
* res.city; // 城市,是一個對象
* res.city.province; // 省
* res.city.city; // 市
* res.city.district; // 區
* res.city.citycode; // 城市代碼

### [3.9.cropImg裁剪圖片](https://www.easyweb.vip/doc/#/?id=_39cropimg%e8%a3%81%e5%89%aa%e5%9b%be%e7%89%87)
~~~
admin.cropImg({
aspectRatio: 1/1,
imgSrc: '../../assets/images/15367146917869444.jpg',
onCrop: function (res) {
// 返回的res是base64編碼的裁剪后的圖片
layer.msg('<img src="' + res + '" width="220px" height="220px"/>');
}
});
~~~
| 參數 | 默認 | 描述 |
| :-- | :-- | :-- |
| title | "裁剪圖片" | 彈窗標題 |
| aspectRatio | 1/1 | 裁剪比例,例如:16/9 |
| imgSrc | 無 | 要裁剪的圖片,無則先彈出選擇圖片 |
| imgType | 'image/jpeg' | 裁剪的圖片類型,非必填 |
| onCrop | 無 | 裁剪完成回調 |
| limitSize | 不限制 | 限制選擇的圖片大小 |
| acceptMime | 'image/\*' | 限制選擇的圖片類型 |
| exts | 不限制 | 限制選擇的圖片后綴 |
* acceptMime參考值:'image/jpg, image/png'(只顯示 jpg 和 png 文件)
* exts參考值:jpg|png|gif|bmp|jpeg

* * *
## [4.admin.css介紹](https://www.easyweb.vip/doc/#/?id=_4admincss%e4%bb%8b%e7%bb%8d)
### [4.1.公共類](https://www.easyweb.vip/doc/#/?id=_41%e5%85%ac%e5%85%b1%e7%b1%bb)
| 類名(class) | 說明 |
| :-- | :-- |
| pull-left | 左浮動 |
| pull-right | 右浮動 |
| text-left | 內容居左 |
| text-center | 內容居中 |
| text-right | 內容居右 |
| inline-block | 設置display為inline-block |
| bg-white | 設置背景為白色 |
| layui-link | 設置a標簽顏色為主題色 |
| text-muted | 文字顏色為灰色 |
| text-success | 文字顏色為綠色,成功色 |
| text-warning | 文字顏色為黃色警告色 |
| text-danger | 文字顏色為紅色危險色 |
| text-info | 文字顏色為藍色信息色 |
| text-primary | 文字顏色為主題色 |
| layui-text | .layui-text下面的a標簽為藍色 |
~~~
<a href="xxx" class="layui-link">帳號注冊</a>
~~~

~~~
<div class="layui-text">
<a href="xxx">xxx</a>
<a href="xxx">xxx</a>
</div>
~~~

### [4.2.組件樣式](https://www.easyweb.vip/doc/#/?id=_42%e7%bb%84%e4%bb%b6%e6%a0%b7%e5%bc%8f)
| 類名(class) | 說明 |
| :-- | :-- |
| icon-btn | 帶圖標的按鈕,會縮小邊距 |
| date-icon | 在元素的右邊加入日期的圖標 |
| search-icon | 在元素的右邊加入搜索的圖標 |
| btn-circle | 圓形按鈕,參見便簽界面 |
| layui-form-select-top | 控制下拉框上彈出,加載select父元素上 |
| xm-select-nri | 多選下拉框去掉最后那個沒用的圖標,加在父元素上 |
| mini-bar | 如果有滾動條,使用細的風格 |
| arrow2 | 設置側邊欄小三角為箭頭圖標,加在layui-nav上 |
| arrow3 | 設置側邊欄小三角為加減號圖標,加在layui-nav上 |
| close-footer | 關閉頁腳,加`<body class="layui-layout-body close-footer">`上 |
| table-tool-mini | 數據表格工具欄mini樣式,加在table父元素上 |
| hide-body-title | 全局隱藏單標簽模式標題欄,加在body上 |
~~~
<!-- 圖標按鈕 -->
<button class="layui-btn icon-btn"><i class="layui-icon"></i>搜索</button>
<!-- 日期圖標 -->
<input class="layui-input date-icon" type="text"/>
<!-- 圓形按鈕 -->
<div class="btn-circle">
<i class="layui-icon layui-icon-add-1"></i>
</div>
<!-- 下拉框上彈出 -->
<div class="layui-form-select-top">
<select>....</select>
</div>
<!-- 多選下拉框去掉最后那個沒用的圖標 -->
<div class="xm-select-nri">
<select xm-select="xx">....</select>
</div>
~~~

### [4.3.表單彈窗](https://www.easyweb.vip/doc/#/?id=_43%e8%a1%a8%e5%8d%95%e5%bc%b9%e7%aa%97)
| 類名(class) | 說明 |
| :-- | :-- |
| model-form | 調整彈窗內的表單的間距使之更好看 |
| model-form-body | 表單內容部分,高度自適應,超過屏幕高度顯示滾動條 |
| model-form-footer | 表單底部按鈕部分,用于固定底部按鈕 |
表單彈窗示例,添加用戶:
~~~
<script type="text/html" id="modelUser">
<form id="modelUserForm" lay-filter="modelUserForm" class="layui-form model-form">
<input name="userId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">賬號</label>
<div class="layui-input-block">
<input name="username" placeholder="請輸入賬號" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">用戶名</label>
<div class="layui-input-block">
<input name="nickName" placeholder="請輸入用戶名" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性別</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男" checked/>
<input type="radio" name="sex" value="女" title="女"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">角色</label>
<div class="layui-input-block">
<select name="roleId" lay-verType="tips" lay-verify="required">
<option value="">請選擇角色</option>
<option value="1">管理員</option>
<option value="2">普通用戶</option>
<option value="3">游客</option>
</select>
</div>
</div>
<div class="layui-form-item text-right">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="modelSubmitUser" lay-submit>保存</button>
</div>
</form>
</script>
<script>
admin.open({
type: 1,
title: '添加用戶',
content: $('#modelUser').html(),
success: function (layero, dIndex) {
}
});
</script>
~~~

固定底部操作按鈕:
~~~
<script type="text/html" id="modelPtInfo">
<form id="modelFormPtInfo" lay-filter="modelFormPtInfo" class="layui-form model-form no-padding">
<div class="model-form-body" style="max-height: 320px;"> <!-- 如果要超出屏幕才固定底部,不要寫max-height -->
<div class="layui-form-item">
<label class="layui-form-label">實習公司</label>
<div class="layui-input-block">
<input name="companyName" placeholder="請輸入實習公司" type="text" class="layui-input"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<!-- ......省略 -->
</div>
<div class="layui-form-item text-right model-form-footer">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="modelSubmitPtInfo" lay-submit>保存</button>
</div>
</form>
</script>
~~~

### [4.4.表格工具欄](https://www.easyweb.vip/doc/#/?id=_44%e8%a1%a8%e6%a0%bc%e5%b7%a5%e5%85%b7%e6%a0%8f)
| 類名(class) | 說明 |
| :-- | :-- |
| toolbar | 調整表格上面的表單間距使之更好看 |
| w-auto | 設置width:auto,用于重置一些有固定寬度表單元素 |
| mr0 | 設置margin-right:0,用于重置一些表單元素的樣式 |
~~~
<div class="layui-form toolbar">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label w-auto">賬 號:</label>
<div class="layui-input-inline mr0">
<input name="username" class="layui-input" type="text" placeholder="輸入賬號"/>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label w-auto">用戶名:</label>
<div class="layui-input-inline mr0">
<input name="nickName" class="layui-input" type="text" placeholder="輸入用戶名"/>
</div>
</div>
<div class="layui-inline">
<button class="layui-btn icon-btn" lay-filter="formSubSearchUser" lay-submit>
<i class="layui-icon"></i>搜索
</button>
<button id="btnAddUser" class="layui-btn icon-btn"><i class="layui-icon"></i>添加</button>
</div>
</div>
</div>
<table class="layui-table" id="tableUser" lay-filter="tableUser"></table>
~~~

移動端下自動適配樣式:

* * *
## [5.主題功能](https://www.easyweb.vip/doc/#/?id=_5%e4%b8%bb%e9%a2%98%e5%8a%9f%e8%83%bd)
1. 使用[主題生成器](https://demo.easyweb.vip/theme/)生成個性化主題;
2. 將生成的css放在`assets/moudel/theme`目錄下;
3. 打開`page/tpl/tpl-theme.html`添加生成的主題:
~~~
var themes = [
{title: '黑白主題', theme: 'admin'},
{title: '黑色主題', theme: 'black'},
{title: '你的主題', theme: 'xxx'}
];
~~~
> 主題css以`theme-xxx.css`的形式命名,主題預覽圖跟主題css名字保持一致,預覽圖可在主題生成器中獲取。
* * *
## [6.擴展插件](https://www.easyweb.vip/doc/#/?id=_6%e6%89%a9%e5%b1%95%e6%8f%92%e4%bb%b6)
### [6.1.鼠標右鍵](https://www.easyweb.vip/doc/#/?id=_61%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae)
快速使用:
~~~
layui.use(['contextMenu'], function () {
var contextMenu = layui.contextMenu;
// 重寫整個頁面右鍵菜單
contextMenu.bind('html', [{
icon: 'layui-icon layui-icon-snowflake',
name: '菜單一',
click: function () {
alert('點擊了菜單一');
}
}, {
name: '菜單二',
click: function () {
alert('點擊了菜單二');
}
}]);
});
~~~
* 參數一: 綁定元素;
* 參數二:菜單數組;
**菜單數組結構:**
~~~
[{
icon: 'xxxxx',
name: '菜單三',
subs: [{
icon: 'xxxxx',
name: '子菜單一',
click: function () {
alert('點擊了子菜單一');
}
}]
}]
~~~
> `icon`:圖標,`name`:菜單名,`click`:點擊事件,`subs`:子菜單(支持無限極)。
**用于點擊事件:**(使用`show`方法)
~~~
$('#btn').click(function (e) {
var x = $(this).offset().left;
var y = $(this).offset().top + $(this).outerHeight();
contextMenu.show([{
name: '按鈕菜單一',
click: function () {
}
}, {
name: '按鈕菜單二',
click: function () {
}
}], x, y);
e.preventDefault();
e.stopPropagation();
});
~~~
* 參數一: 菜單數組;
* 參數二三:xy坐標;
### [6.2.打印插件](https://www.easyweb.vip/doc/#/?id=_62%e6%89%93%e5%8d%b0%e6%8f%92%e4%bb%b6)
**打印當前頁面:**
~~~
printer.print();
printer.print({
hide: ['.layui-btn', '#btn01'], // 打印時隱藏的元素
horizontal: true, // 是否橫向打印
blank: true, // 是否打開新頁面打印
close: true, // 如果是打開新頁面,打印完是否關閉
iePreview: true // 是否兼容ie打印預覽
});
~~~
> 參數都是可以選參數,默認值已經符合大多數需求。
**設置不打印的元素:**
~~~
<div class="hide-print">非打印內容</div>
~~~
> 加`hide-print`這個class即可,可以跟`hide`參數疊加使用。
**打印自定義內容:**
~~~
printer.printHtml({
html: '<span>xxxx</span>', // 要打印的內容
horizontal: true, // 是否橫向打印
blank: true, // 是否打開新頁面打印
close: true, // 如果是打開新頁面,打印完是否關閉
iePreview: true, // 是否兼容ie打印預覽
print: true // 如果是打開新窗口是否自動打印
});
~~~
?打印表格時可以給table加`print-table`這個class來設置表格的邊框樣式:
。
**分頁打印:**
~~~
printer.printPage({
htmls: [
'<span>xxxx</span>', // 要打印的內容
'<span>xxxx</span>'
],
style: '<style> span { color: red; } </style>', // 頁面樣式
horizontal: true, // 是否橫向打印
padding: undefined, // 頁面間距,例如寫'10px'
debug: false, // 調試模式
blank: true, // 是否打開新頁面打印
close: true, // 如果是打開新頁面,打印完是否關閉
iePreview: true, // 是否兼容ie打印預覽
print: true // 如果是打開新窗口是否自動打印
});
~~~
參數都是可選參數:
* htmls?數組,代表每一頁;
* style?樣式,也可以寫`<link rel="stylesheet">`的形式;
* padding?間距,undefined表示使用打印機默認間距,如果自定義間距,打印機間距要選擇無;
* debug?調試模式,每一頁會加紅色邊框,便于調試大小;
> `padding`為undefined表示使用打印機默認間距,插件內部會根據不同瀏覽器做兼容處理,因為不同瀏覽器的默認間距不同, 目前對谷歌、IE、Edge、火狐做了兼容處理,safari、歐朋后續會考慮。
**makeHtml()拼接html:**
~~~
var htmlStr = printer.makeHtml({
title: '網頁標題',
style: '<link rel="stylesheet" href="layui.css"><script type="text/javascript" src="layui.js"><\/script>',
body: $('#xxx').html()
});
~~~
**其他方法:**
~~~
printer.isIE();
printer.isEdge();
printer.isFirefox();
~~~
**打印任意url:**
目前沒有提供直接的方法,可以使用ajax請求到url的html內容,在使用printHtml方法打印:
~~~
$.ajax({
url: 'xxx.html',
type: 'get',
dataType: 'html',
success: function (res) {
printer.printHtml({
html: res, // 要打印的內容
horizontal: true // 是否橫向打印
});
}
});
~~~
> 另外js直接控制橫向打印只支持谷歌內核的瀏覽器,火狐不支持js調用打印預覽, 火狐打印預覽可以通過設置`blank:true,print:false`然后手動選擇打印預覽。
### [6.3.tableX表格擴展](https://www.easyweb.vip/doc/#/?id=_63tablex%e8%a1%a8%e6%a0%bc%e6%89%a9%e5%b1%95)
| 方法 | 參數 | 描述 |
| :-- | :-- | :-- |
| merges(tableId, indexs, fields) | 見單獨說明 | 合并單元格 |
| bindCtxMenu(tableId, items) | 見單獨說明 | 給表格行綁定鼠標右鍵 |
| render(object) | 同layui表格 | 渲染表格,帶后端排序功能 |
| renderFront(object) | 同layui表格 | 渲染表格,帶前端分頁、排序、模糊搜索、刷新功能 |
| exportData(object) | 見單獨說明 | 導出任意數據為excel |
| loadUrl(object, callback) | 見單獨說明 | 請求表格數據 |
| parseTbData(cols, dataList, overwrite) | 見單獨說明 | 獲取解析templet后數據 |
| filterData(dataList, searchName, searchValue) | 見單獨說明 | 前端搜索數據 |
| deepClone(object) | 任意對象 | 深度克隆對象 |
#### [6.3.1.merges合并單元格](https://www.easyweb.vip/doc/#/?id=_631merges%e5%90%88%e5%b9%b6%e5%8d%95%e5%85%83%e6%a0%bc)
~~~
layui.use(['tableX'], function () {
var tableX = layui.tableX;
table.render({
elem: '#xTable2',
url: '../../json/tablex1.json',
cols: [[
{type: 'numbers'},
{field: 'parentName', title: '模塊名稱', sort: true},
{field: 'authorityName', title: '菜單名稱', sort: true}
]],
done: function () {
tableX.merges('xTable2', [1]); // 在done回調里面調用
}
});
});
~~~
使用方法:
~~~
tableX.merges('xTable2', [1]); // 合并第2列相同的單元格
tableX.merges('xTable2', [1], ['parentName']); // 合并第2列相同的單元格
tableX.merges('xTable2', [1, 2]); // 合并第2、3列相同的單元格
tableX.merges('xTable2', [1, 2], ['parentName', 'authorityName']); // 合并第2、3列相同的單元格
tableX.merges('xTable2', [1, 2], false); // 在后面加一個false可解決排序沖突的問題
~~~
* 參數一 ? 必填 ?? 表格的lay-filter
* 參數二 ? 必填 ?? 要合并列的索引,數組類型
* 參數三 ? 非必填 ? 根據數據字段判斷是否相同,為空時根據單元格的html內容判斷
#### [6.3.2.bindCtxMenu行綁定鼠標右鍵](https://www.easyweb.vip/doc/#/?id=_632bindctxmenu%e8%a1%8c%e7%bb%91%e5%ae%9a%e9%bc%a0%e6%a0%87%e5%8f%b3%e9%94%ae)
~~~
table.render({
elem: '#xTable3',
url: '../../json/user.json',
cols: [[
{field: 'nickName', title: '用戶名', sort: true},
{field: 'sex', title: '性別', sort: true}
]],
done: function () {
// 在done回調里面綁定
tableX.bindCtxMenu('xTable3', [{
icon: 'layui-icon layui-icon-edit',
name: '修改此用戶',
click: function (d) {
layer.msg('點擊了修改,userId:' + d.userId);
}
}, {
icon: 'layui-icon layui-icon-close text-danger',
name: '<span class="text-danger">刪除此用戶</span>',
click: function (d) {
layer.msg('點擊了刪除,userId:' + d.userId);
}
}]);
}
});
~~~
* 參數一 ? 表格的lay-filter
* 參數二 ? 右鍵菜單
* icon ??? 圖標
* name ? 標題
* click ??? 點擊事件,d是當前行的數據
#### [6.3.3.render后端排序](https://www.easyweb.vip/doc/#/?id=_633render%e5%90%8e%e7%ab%af%e6%8e%92%e5%ba%8f)
~~~
tableX.render({
elem: '#xTable3',
url: '../../json/user.json',
cols: [[
{type: 'numbers'},
{field: 'nickName', title: '用戶名', sort: true},
{field: 'sex', title: '性別', sort: true}
]]
});
~~~
?僅僅是把`table.render`換成`tableX.render`就會在點擊排序時自動傳遞`sort`和`order`參數,例如:user?page=1&limit=10&sort=sex&order=asc。
* sort ??? 排序字段,值是點擊排序列的field
* order ? 排序方式,升序是asc,降序是desc
> 注意:如果寫了sort: true開啟排序,一定要寫field: 'xxx'。
#### [6.3.4.renderFront前端分頁排序](https://www.easyweb.vip/doc/#/?id=_634renderfront%e5%89%8d%e7%ab%af%e5%88%86%e9%a1%b5%e6%8e%92%e5%ba%8f)
~~~
tableX.renderFront({
elem: '#xTable1',
url: '../../json/userAll.json',
page: { groups: 6 },
cols: [[
{type: 'checkbox'},
{field: 'nickName', title: '用戶名', sort: true},
{field: 'sex', title: '性別', sort: true}
]]
});
~~~
?僅僅是把`table.render`換成`tableX.renderFront`就可以有前端分頁和排序功能了,參數跟layui表格的參數一摸一樣,url方式你的接口可以返回全部數據,前端來分頁,也支持data方式。
**前端模糊搜索:**
~~~
<input tb-search="xTable1" class="layui-input icon-search" type="text"/>
~~~
?頁面中加入上面的輸入框,通過`tb-search`關聯表格,就實現了對表格的模糊搜索功能,你可以對該input加任意樣式,放在任意位置。
?還可以增加name屬性來設置搜索時只搜索某些字段,多個字段通過逗號分隔:
~~~
<input tb-search="xTable1" name="sex,phone" class="layui-input icon-search" type="text"/>
~~~
**刷新功能:**
~~~
<!-- 通過tb-refresh綁定刷新按鈕 -->
<button tb-refresh="xTable1" class="layui-btn">刷新</button>
~~~
?也可以通過js刷新:
~~~
var insTb = tableX.renderFront('.....省略');
insTb.reloadUrl(); // url方式刷新
insTb.reloadData({data: dataList, page: {curr: 1}}); // data方式的刷新
~~~
> 注意:url方式的前端分頁使用reloadUrl()方法,reloadUrl()方法暫時不支持加參數,reloadData方法跟table.reload()方法參數一致。
**前端排序:**
?前端排序如果有field字段,會根據field字段的值來排序,如果沒有field有templet會根據templet轉換后的值排序, templet可能會返回表單元素,比如switch開關等,這些元素根本無法用來排序,那么可以通過`export-show`和`export-hide`這兩個東西來控制。
~~~
<!-- 開關,state=0開關打開,state=1開關關閉 -->
<script type="text/html" id="tableState">
<input type="checkbox" lay-skin="switch" lay-text="正常|鎖定" lay-filter="ckState" value="{{d.userId}}" {{d.state==0?'checked':''}}/>
<div class="export-show">{{d.state==0?'正常':'鎖定'}}</div>
</script>
<!-- 圖標,state=0顯示ok的圖標,state=1顯示叉叉的圖標 -->
<script type="text/html" id="tableState">
<div class="export-hide">{{d.state==0?'<i class="layui-icon layui-icon-ok"></i>':'<i class="layui-icon layui-icon-close"></i>'}}</div>
<div class="export-show">{{d.state==0?'正常':'鎖定'}}</div>
</script>
<!-- 圖標和開關沒法用于排序,可以寫兩份,一份用于表格展示,一份用于排序和導出功能 -->
~~~
* `export-hide`用于表格展示,但是對排序和導出時屏蔽
* `export-show`用于排序和導出功能獲取單元格數據,但是對表格展示時屏蔽
> 排序建議最好是通過field來根據數據的字段排序,field不支持d.xxx.xxx這種嵌套的對象,就需要用上面的方法
#### [6.3.5.exportData導出任意數據](https://www.easyweb.vip/doc/#/?id=_635exportdata%e5%af%bc%e5%87%ba%e4%bb%bb%e6%84%8f%e6%95%b0%e6%8d%ae)
~~~
tableX.exportData({
cols: insTb.config.cols, // 表頭配置
data: table.cache.xTable3, // 數據,支持url方式
fileName: '用戶表' // 文件名稱
});
~~~
| 參數 | 必填 | 說明 | 默認 |
| :-- | :-- | :-- | :-- |
| cols | 是 | 表頭配置 | |
| data | 是 | 導出的數據,支持數組和string的url | |
| fileName | 否 | 導出的文件名稱 | table |
| expType | 否 | 導出的文件類型 | xls |
| option | 否 | url方式的配置 | |
?如果data是string類型會把data當url請求數據,option是請求的配置,跟表格的配置一樣,配置method、where、headers等,接口返回的格式也要跟表格一樣包含code、count、data等信息。
?cols的配置也跟表格一樣,是一個多維數組,可以通過`insTb3.config.cols`來獲取表格的cols,也可以重寫。
**導出的數據會包含templet轉換:**
~~~
tableX.renderFront({
elem: '#xTable1',
url: '../../json/userAll.json',
page: { groups: 6 },
cols: [[
{type: 'checkbox'},
{field: 'nickName', title: '用戶名', sort: true},
{field: 'sex', title: '性別', sort: true},
{
title: '狀態', templet: function (d) {
var stateStr = ['正常', '凍結', '欠費'];
return stateStr[d.state];
}
}
]]
});
~~~
?像上面這種state數據存的是0和1,但是顯示是文字,導出數據會自動轉成文字(layui2.5后自帶的帶出也包含此功能)。
?如果列是表單元素,比如switch開關,導出的方法:
~~~
<!-- 狀態列 -->
<script type="text/html" id="tableState">
<input type="checkbox" lay-skin="switch" lay-text="正常|鎖定" lay-filter="ckState" value="{{d.userId}}" {{d.state==0?'checked':''}}/>
<div class="export-show">{{d.state==0?'正常':'鎖定'}}</div>
</script>
<script>
layui.use(['tableX'], function () {
var tableX = layui.tableX;
tableX.render({
elem: '#xTable3',
url: '../../json/user.json',
cols: [[
{field: 'nickName', title: '用戶名', sort: true},
{field: 'phone', title: '手機號', sort: true},
{field: 'state', templet: '#tableState', title: '狀態', sort: true}
]]
});
});
</script>
~~~
?通過加一個`export-show`類可以保證里面的內容只作為導出的時候用,不作為表格展示,還可以加`export-hide`來設置導出的時候屏蔽的內容。
~~~
<!-- 圖標,state=0顯示ok的圖標,state=1顯示叉叉的圖標 -->
<script type="text/html" id="tableState">
<div class="export-hide">{{d.state==0?'<i class="layui-icon"></i>':'<i class="layui-icon">ဆ</i>'}}</div>
<div class="export-show">{{d.state==0?'正常':'鎖定'}}</div>
</script>
<!-- 不可能把圖標的unicode字符導出吧,那就寫兩份,一份用于表格展示,一份用于排序和導出功能 -->
~~~
* `export-hide`用于表格展示,但是對排序和導出時屏蔽
* `export-show`用于排序和導出功能獲取單元格數據,但是對表格展示時屏蔽
### [6.4.formX表單擴展](https://www.easyweb.vip/doc/#/?id=_64formx%e8%a1%a8%e5%8d%95%e6%89%a9%e5%b1%95)
后續推出...
### [6.5.樹形表格](https://www.easyweb.vip/doc/#/?id=_65%e6%a0%91%e5%bd%a2%e8%a1%a8%e6%a0%bc)
[前往碼云查看](https://gitee.com/whvse/treetable-lay)
### [6.6.下拉菜單](https://www.easyweb.vip/doc/#/?id=_66%e4%b8%8b%e6%8b%89%e8%8f%9c%e5%8d%95)
快速使用:
~~~
<!-- click模式觸發 -->
<div class="dropdown-menu">
<button class="layui-btn icon-btn">
Click me <i class="layui-icon layui-icon-drop"></i>
</button>
<ul class="dropdown-menu-nav">
<li><a>1st menu item</a></li>
<li><a>2nd menu item</a></li>
<li><a>3rd menu item</a></li>
</ul>
</div>
<!-- hover模式觸發,增加dropdown-hover即可 -->
<div class="dropdown-menu dropdown-hover">
<button class="layui-btn icon-btn">
Hover me <i class="layui-icon layui-icon-drop"></i></button>
<ul class="dropdown-menu-nav">
<li><a>1st menu item</a></li>
<li><a>2nd menu item</a></li>
<li><a>3rd menu item</a></li>
</ul>
</div>
<script>
layui.use(['dropdown'], function () {
var dropdown = layui.dropdown; // 加載模塊
});
</script>
~~~

更多樣式:
~~~
<!-- 標題及禁用樣式 -->
<div class="dropdown-menu dropdown-hover">
<button class="layui-btn icon-btn">
更多樣式 <i class="layui-icon layui-icon-drop"></i></button>
<ul class="dropdown-menu-nav">
<li class="title">HEADER</li>
<li><a><i class="layui-icon layui-icon-star-fill"></i>1st menu item</a></li>
<li class="disabled">
<a><i class="layui-icon layui-icon-template-1"></i>2nd menu item</a></li>
<hr>
<li class="title">HEADER</li>
<li><a><i class="layui-icon layui-icon-set-fill"></i>3rd menu item</a></li>
</ul>
</div>
<!-- 帶小三角樣式 -->
<div class="dropdown-menu dropdown-hover">
<button class="layui-btn icon-btn">
帶小三角 <i class="layui-icon layui-icon-drop"></i>
</button>
<ul class="dropdown-menu-nav">
<div class="dropdown-anchor"></div>
<li><a>1st menu item</a></li>
<li><a>2nd menu item</a></li>
<li><a>3rd menu item</a></li>
</ul>
</div>
<!-- 暗色主題 -->
<div class="dropdown-menu">
<button class="layui-btn layui-btn-normal icon-btn">
暗色主題 <i class="layui-icon layui-icon-drop"></i></button>
<ul class="dropdown-menu-nav dark">
<div class="dropdown-anchor"></div>
<li class="title">HEADER</li>
<li><a><i class="layui-icon layui-icon-star-fill"></i>1st menu item</a></li>
<li class="disabled">
<a><i class="layui-icon layui-icon-template-1"></i>2nd menu item</a></li>
<hr>
<li class="title">HEADER</li>
<li><a><i class="layui-icon layui-icon-set-fill"></i>3rd menu item</a></li>
</ul>
</div>
~~~

對任意元素都可以綁定,不一定是按鈕:
~~~
<div class="dropdown-menu dropdown-hover">
<input type="text" placeholder="一個會跳舞的輸入框" class="layui-input"/>
<ul class="dropdown-menu-nav">
<li class="title">是不是在找</li>
<li><a>另一個會跳舞的下拉框</a></li>
<li><a>一杯憂郁的可樂</a></li>
</ul>
</div>
~~~

帶遮罩層,遮罩層是分離式的綁定,通過data-dropdown綁定:
~~~
<button class="layui-btn layui-btn-normal icon-btn" data-dropdown="#dropdown1">
帶遮罩層 <i class="layui-icon layui-icon-drop"></i>
</button>
<!-- 下拉菜單 -->
<ul class="dropdown-menu-nav dropdown-bottom-right layui-hide" id="dropdown1">
<div class="dropdown-anchor"></div>
<li class="title">HEADER</li>
<li><a><i class="layui-icon layui-icon-star-fill"></i>1st menu item</a></li>
<li class="disabled">
<a><i class="layui-icon layui-icon-template-1"></i>2nd menu item</a></li>
<hr>
<li class="title">HEADER</li>
<li><a><i class="layui-icon layui-icon-set-fill"></i>3rd menu item</a></li>
</ul>
~~~

自定義下拉里面的內容:
~~~
<div class="dropdown-menu">
<button class="layui-btn layui-btn-normal icon-btn">
克隆/下載 <i class="layui-icon layui-icon-drop"></i></button>
<div class="dropdown-menu-nav dropdown-bottom-right"
style="width: 280px;padding: 0 10px 10px 10px;">
<div class="dropdown-anchor"></div>
<!-- 下面是自定義內容 -->
<div class="layui-tab layui-tab-brief">
<ul class="layui-tab-title">
<li class="layui-this">HTTPS</li>
<li>SSH</li>
</ul>
<div class="layui-tab-content" style="padding: 10px 0 10px 0;">
<div class="layui-tab-item layui-show">
<input class="layui-input" value="https://gitee.com/whvse/easyweb-jwt.git"/>
</div>
<div class="layui-tab-item">
<input class="layui-input" value="git@gitee.com:whvse/easyweb-jwt.git"/>
</div>
</div>
</div>
<button class="layui-btn layui-btn-sm layui-btn-fluid" style="margin-bottom: 10px;">
Download ZIP
</button>
<img src="http://p1.music.126.net/voV3yPduAhNATICMRJza1A==/109951164017919367.jpg"
width="100%">
<!-- //end.自定義內容結束 -->
</div>
</div>
~~~

控制顯示方向,在dropdown-menu-nav上加dropdown-bottom-center等位置:
| 類名 | 位置 |
| :-- | :-- |
| dropdown-bottom-left | 下左彈出 |
| dropdown-bottom-center | 下中彈出 |
| dropdown-bottom-right | 下右彈出 |
| dropdown-top-left | 上左彈出 |
| dropdown-top-center | 上中彈出 |
| dropdown-top-right | 上右彈出 |
| dropdown-left-top | 左上彈出 |
| dropdown-left-center | 左中彈出 |
| dropdown-left-bottom | 左下彈出 |
| dropdown-right-top | 右上彈出 |
| dropdown-right-center | 右中彈出 |
| dropdown-right-bottom | 右下彈出 |
~~~
<!-- Bottom Center -->
<div class="dropdown-menu dropdown-hover">
<button class="layui-btn layui-btn-primary icon-btn">
Bottom <i class="layui-icon layui-icon-drop"></i> Center
</button>
<ul class="dropdown-menu-nav dropdown-bottom-center"><!-- 這里加控制方向的類 -->
<div class="dropdown-anchor"></div>
<li><a>1st menu item</a></li>
<li><a>2nd menu item</a></li>
<li><a>3rd menu item</a></li>
</ul>
</div>
<!-- Bottom Right -->
<div class="dropdown-menu dropdown-hover">
<button class="layui-btn layui-btn-primary icon-btn">
Bottom Right <i class="layui-icon layui-icon-drop"></i>
</button>
<ul class="dropdown-menu-nav dropdown-bottom-right"><!-- 這里加控制方向的類 -->
<div class="dropdown-anchor"></div>
<li><a>1st menu item</a></li>
<li><a>2nd menu item</a></li>
<li><a>3rd menu item</a></li>
</ul>
</div>
~~~

### [6.7.消息通知](https://www.easyweb.vip/doc/#/?id=_67%e6%b6%88%e6%81%af%e9%80%9a%e7%9f%a5)
~~~
layui.use(['notice'], function(){
var notice = layui.notice;
// 通知樣式
notice.success({
title: '消息通知',
message: '你有新的消息,請注意查收!'
});
// 提示框樣式,1成功、2失敗、3警告、4加載、5信息(藍色圖標)
notice.msg('Hello', {icon: 1});
});
~~~
**方法:**
| 方法 | 參數 | 說明 |
| :-- | :-- | :-- |
| success(object) | 見下方 | 成功消息(綠色) |
| warning(object) | 見下方 | 警告消息(黃色) |
| error(object) | 見下方 | 錯誤消息(紅色) |
| info(object) | 見下方 | 通知消息(藍色) |
| show(object) | 見下方 | 自定義樣式 |
| msg(string, object) | 內容,其他配置 | 提示框 |
| destroy() | 無 | 關閉全部 |
| hide(object, toast, closedBy) | 見下方 | 關閉指定的通知 |
| settings(object) | 見下方 | 統一設置默認值 |
**參數:**
| 參數 | 說明 | 默認值 | 可選值 |
| :-- | :-- | :-- | :-- |
| title | 標題 | 無 | string類型 |
| message | 內容 | 無 | string類型 |
| position | 顯示位置 | topRight | 見下方 |
| transitionIn | 進入動畫 | fadeInLeft | 見下方 |
| transitionOut | 退出動畫 | fadeOutRight | 見下方 |
| timeout | 消失時間 | 5000 | 單位毫秒,false永不消失 |
| progressBar | 進度條 | true | true顯示、false不顯示 |
| balloon | 氣泡效果 | false | true開啟、false關閉 |
| close | 關閉按鈕 | true | true顯示,false不顯示 |
| pauseOnHover | 鼠標滑過暫停消失時間 | true | true、false |
| resetOnHover | 鼠標滑過重置消失時間 | false | true、false |
| animateInside | 文字動畫效果 | false | true開啟、false關閉 |
| className | 自定義class | 無 | 多個用空格分隔 |
| theme | 主題 | light | light、dark |
| audio | 音效 | 無 | 1,2,3,4,5,6 |
| image | 顯示圖片 | 無 | 圖片地址 |
| imageWidth | 圖片寬度 | 60 | 數字 |
| buttons | 顯示按鈕 | \[\] | \[ \[ 'btn1', function(){} \], \['btn2', function(){} \] \] |
| overlay | 遮罩層 | false | true顯示,false不顯示 |
| drag | 滑動關閉 | true | true開啟,false關閉 |
| layout | 布局類型 | 2 | 1標題和內容并排,2兩排顯示 |
| rtl | 布局方向 | false | false內容居左,true居右 |
| displayMode | 顯示模式 | 0 | 0無限制,1同類型存在不顯示,2同類型存在先移除 |
| targetFirst | 插入方式 | 自動 | true從上插入,false下插入,null自動 |
| onOpened | 打開后回調函數 | 無 | function |
| onClosed | 關閉后回調函數 | 無 | function |
| titleColor | 標題顏色 | 默認 | 顏色單位 |
| titleSize | 標題大小 | 默認 | 尺寸單位 |
| messageColor | 文字顏色 | 默認 | 顏色單位 |
| messageSize | 文字大小 | 默認 | 尺寸單位 |
| backgroundColor | 背景顏色 | 默認 | 顏色單位 |
| progressBarColor | 進度條顏色 | 默認 | 顏色單位 |
| maxWidth | 最大寬度 | null | 尺寸單位 |
**顯示位置可選屬性:**
`bottomRight`、`bottomLeft`、`topRight`、`topLeft`、`topCenter`、`bottomCenter`、`center`。
**進入動畫可選屬性:**
`bounceInLeft`,`bounceInRight`,`bounceInUp`,`bounceInDown`,`fadeIn`,`fadeInDown`,`fadeInUp`,`fadeInLeft`,`fadeInRight`,`flipInX`。
**退出動畫可選屬性:**
`fadeOut`,`fadeOutUp`,`fadeOutDown`,`fadeOutLeft`,`fadeOutRight`,`flipOutX`。
**統一設置默認值:**
~~~
notice.settings({
timeout: 10000,
transitionIn: 'flipInX',
onOpen: function(){
console.log('callback abriu!');
}
});
~~~
**關閉指定的通知**
~~~
notice.hide({}, document.querySelector('.toast'));
~~~
* 參數一 ? 重寫一些參數,比如關閉動畫等
* 參數二 ? 根據自定義的className選擇關閉的對象
### [6.8.文件選擇彈窗](https://www.easyweb.vip/doc/#/?id=_68%e6%96%87%e4%bb%b6%e9%80%89%e6%8b%a9%e5%bc%b9%e7%aa%97)
快速使用:
~~~
layui.use(['fileChoose'], function () {
var fileChoose = layui.fileChoose;
fileChoose.open({
fileUrl: '', // 文件查看的url
listUrl: '../template/file/files.json', // 文件列表的url
where: {
access_token: 'xxxxxx'
},
num: 3, // 最多選擇數量
dialog: {
offset: '60px'
},
onChoose: function (urls) {
layer.msg('你選擇了:' + JSON.stringify(urls), {icon: 1});
}
});
});
~~~
參數:
| 參數 | 描述 | 默認值 |
| --- | --- | --- |
| fileUrl | 文件查看的url | |
| listUrl | 文件列表的url | |
| where | 文件列表請求參數 | {} |
| num | 文件選擇的數量 | 1 |
| onChoose | 選擇后回調 | |
| upload | 文件上傳配置(同layui配置) | {} |
| dialog | 彈窗配置(同layui配置) | {} |
| menu | 點擊彈出的菜單 | 數組類型 |
| menuClick | 菜單點擊事件處理 | |
| response | 接口數據格式化 | |
菜單配置及點擊事件:
~~~
fileChoose.open({
menu: [{
name: '預覽',
event: 'preview'
}, {
name: '復制',
event: 'copy'
}, {
name: '<span style="color: red;">刪除</span>',
event: 'del'
}],
menuClick: function(event, item) {
// event 事件名稱
// item 當前數據
}
});
~~~
?name菜單項名稱,event點擊事件名稱
接口數據格式化:
~~~
fileChoose.open({
response: {
method: 'get', // 請求方式
code: 0, // 成功碼,默認200
name: 'name', // 文件名稱字段名稱
url: 'url', // 文件url字段名稱
smUrl: 'smUrl', // 文件縮略圖字段名稱
isDir: 'isDir', // 是否是文件夾字段名稱,boolean類型
dir: 'dir' // 當前文件夾參數名稱
}
});
~~~
接口數據返回的格式需要為:
~~~
{
"code": 200,
"msg": "請求成功",
"data": [
{
"name": "圖片一",
"url": "2019/07/11/001.png",
"smUrl": "sm/2019/07/11/001.png",
"isDir": false
}
]
}
~~~
?code、msg、data是必須按這個名字的,name、url、smUrl、isDir這幾個字段的名稱可以通過response參數配置,也可以加其他字段, 比如id、create\_time等,這些字段會在菜單點擊事件和選擇回調事件中返回。
?如果你的接口返回的數據不是code、msg,是其他的,比如status、message,可以使用parseData參數格式化:
~~~
fileChoose.open({
response: {
parseData: function(res){
return {
code: res.status,
msg: res.message,
data: res.list
}
}
}
});
~~~
?如果是文件夾,點擊文件夾會重新請求接口,并且傳遞文件夾的名稱,傳遞的字段名稱可以通過response.dir修改。
?不同文件顯示不同的圖標是前端根據文件url的后綴名稱來判斷的,在之前版本是服務器根據文件的content-type判斷的。

### [6.9.標簽輸入框](https://www.easyweb.vip/doc/#/?id=_69%e6%a0%87%e7%ad%be%e8%be%93%e5%85%a5%e6%a1%86)
模塊名:tagsInput,使用方法:
~~~
<input id="demoTagsInput" value="辣妹子,大長腿" class="layui-hide"/>
<script>
layui.use(['jquery', 'tagsInput'], function () {
var $ = layui.jquery;
// 輸入框樣式
$('#demoTagsInput').tagsInput();
// 無邊框樣式
$('#demoTagsInput').tagsInput({skin: 'tagsinput-default'});
// BackSpace鍵可刪除標簽
$('#demoTagsInput').tagsInput({removeWithBackspace: true});
// 輸入列表提示
$('#demoTagsInput').tagsInput({
skin: 'tagsinput-default',
autocomplete_url: '../../json/tagsInput.json'
});
});
</script>
~~~
?只需要寫一個input框,調用tagsInput方法渲染即可,回顯數據寫在value中用逗號分隔。
參數說明:
| 參數 | 說明 | 默認值 |
| --- | --- | --- |
| defaultText | 提示文字 | +請輸入 |
| skin | 樣式風格 | |
| removeWithBackspace | 回退鍵可刪除已添加的標簽 | false |
| focusWithClick | 點擊已添加標簽輸入框獲取焦點 | true |
| autocomplete\_url | 自動提示接口url | |
| autocomplete | 接口配置 | |
autocomplete參數:
~~~
$('#demoTagsInput').tagsInput({
autocomplete_url: '../../json/tagsInput.json',
autocomplete: {
type: 'post',
data: {
access_token: 'xxxxx'
}
}
});
~~~
?type是請求方式,默認是get請求,data是額外參數,請求autocomplete\_url會傳遞`name`參數(輸入框的值)。

> 此插件基于[jQuery-Tags-Input](https://github.com/xoxco/jQuery-Tags-Input)二次修改。
### [6.10.鼠標滾輪監聽](https://www.easyweb.vip/doc/#/?id=_610%e9%bc%a0%e6%a0%87%e6%bb%9a%e8%bd%ae%e7%9b%91%e5%90%ac)
模塊名:mousewheel,使用方式:
~~~
layui.use(['mousewheel'], function () {
var $ = layui.jquery;
// 滾動監聽
$('#xxx').on('mousewheel', function (event) {
console.log(event.deltaX, event.deltaY, event.deltaFactor);
event.stopPropagation(); // 阻止事件冒泡
event.preventDefault(); // 阻止默認事件
});
});
~~~
event對象中可以獲取如下三個屬性值:
* deltaX:值為負的(-1),則表示滾輪向左滾動。值為正的(1),則表示滾輪向右滾動。
* deltaY:值為負的(-1),則表示滾輪向下滾動。值為正的(1),則表示滾輪向上滾動。
* deltaFactor:增量因子。通過 deltaFactor \* deltaX 或者 deltaFactor \* deltaY 可以得到瀏覽器實際的滾動距離。
> 此插件來源于[jquery-mousewheel](https://github.com/jquery/jquery-mousewheel)。
### [6.11.二維碼模塊](https://www.easyweb.vip/doc/#/?id=_611%e4%ba%8c%e7%bb%b4%e7%a0%81%e6%a8%a1%e5%9d%97)
模塊名:QRCode,使用方式:
~~~
<div id="xxx"></div>
<script>
layui.use(['QRCode'], function () {
var $ = layui.jquery;
var QRCode = layui.QRCode;
// 二維碼
var demoQrCode = new QRCode(document.getElementById("xxx"), {
text: "Hello Word!",
width: 101, // 寬度
height: 101, // 高度
colorDark: "#000000", // 顏色
colorLight: "#ffffff", // 背景顏色
correctLevel: QRCode.CorrectLevel.H
});
// 更換內容
demoQrCode.makeCode("Easyweb");
});
</script>
~~~
> 此插件來源于[qrcodejs](https://github.com/davidshimjs/qrcodejs)。
### [6.12.引導插件](https://www.easyweb.vip/doc/#/?id=_612%e5%bc%95%e5%af%bc%e6%8f%92%e4%bb%b6)
模塊名:introJs,使用方式:
~~~
<p data-step="1" data-intro="這是步驟一">步驟一</p>
<p data-step="2" data-intro="這是步驟二">步驟二</p>
<script>
layui.use(['introJs'], function () {
var introJs = layui.introJs;
// 初始化
introJs().start();
});
</script>
~~~
> 此插件基于[intro.js](https://github.com/usablica/intro.js)二次修改。
### [6.13.剪貼板](https://www.easyweb.vip/doc/#/?id=_613%e5%89%aa%e8%b4%b4%e6%9d%bf)
模塊名:ClipboardJS,使用方式:
~~~
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
<button class="btn" data-clipboard-target="#foo">復制</button>
<script>
layui.use(['ClipboardJS'], function () {
var ClipboardJS = layui.ClipboardJS;
var clipboard = new ClipboardJS('.btn');
clipboard.on('success', function(e) {
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
});
});
</script>
~~~
> 此插件來源于[clipboard.js](https://zenorocha.github.io/clipboard.js)。
* * *
## [7.常見問題](https://www.easyweb.vip/doc/#/?id=_7%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98)
### [7.1 后臺生成側邊欄](https://www.easyweb.vip/doc/#/?id=_71-%e5%90%8e%e5%8f%b0%e7%94%9f%e6%88%90%e4%be%a7%e8%be%b9%e6%a0%8f)
這里用java的一個模板引擎beetl的語法示例:
~~~
<ul class="layui-nav layui-nav-tree" lay-filter="admin-side-nav">
<% for(menu in menus) { %>
<li class="layui-nav-item">
<a lay-href="${menu.menuUrl}"><i class="${menu.menuIcon}"></i> <cite>${menu.menuName}</cite></a>
<% if(menu.subMenus.~size>0) { %>
<dl class="layui-nav-child">
<% for(subMenu in menu.subMenus) { %>
<dd>
<a lay-href="${subMenu.menuUrl}">${subMenu.menuName}</a>
<% if(subMenu.subMenus.~size>0) { %>
<dl class="layui-nav-child">
<% for(temp in subMenu.subMenus) { %>
<dd><a lay-href="${temp.menuUrl}">${temp.menuName}</a></dd>
<% } %>
</dl>
<% } %>
</dd>
<% } %>
</dl>
<% } %>
</li>
<% } %>
</ul>
~~~
### [7.2 ajax加載側邊欄](https://www.easyweb.vip/doc/#/?id=_72-ajax%e5%8a%a0%e8%bd%bd%e4%be%a7%e8%be%b9%e6%a0%8f)
演示地址:[side-ajax.html](https://demo.easyweb.vip/iframe/page/template/side-ajax.html)
~~~
<div class="layui-side">
<div class="layui-side-scroll">
<ul class="layui-nav layui-nav-tree" lay-filter="admin-side-nav"></ul>
</div>
</div>
<script id="sideNav" type="text/html">
{{# layui.each(d, function(index, item){ }}
<li class="layui-nav-item">
<a lay-href="{{item.url}}"><i class="{{item.icon}}"></i> <cite>{{item.name }}</cite></a>
{{# if(item.subMenus&&item.subMenus.length>0){ }}
<dl class="layui-nav-child">
{{# layui.each(item.subMenus, function(index, subItem){ }}
<dd>
<a lay-href="{{ subItem.url }}">{{ subItem.name }}</a>
{{# if(subItem.subMenus&&subItem.subMenus.length>0){ }}
<dl class="layui-nav-child">
{{# layui.each(subItem.subMenus, function(index, thrItem){ }}
<dd><a lay-href="{{ thrItem.url }}">{{ thrItem.name }}</a></dd>
{{# }); }}
</dl>
{{# } }}
</dd>
{{# }); }}
</dl>
{{# } }}
</li>
{{# }); }}
</script>
<script>
layui.use([ 'element', 'admin','laytpl'], function () {
var $ = layui.jquery;
var admin = layui.admin;
var laytpl = layui.laytpl;
var element = layui.element;
$.get('json/side.json', function (res) {
laytpl(sideNav.innerHTML).render(res.data, function (html) {
$('*[lay-filter=admin-side-nav]').html(html);
element.render('nav'); // 這里非常重要
});
}, 'json');
});
</script>
~~~
json數據格式:
~~~
{
"code": 200,
"msg": "",
"data": [{
"name": "系統管理",
"icon": "layui-icon layui-icon-set",
"url": "javascript:;",
"subMenus": [
{
"name": "用戶管理",
"url": "system/user.html"
}
]
}
]
}
~~~
### [7.3 多系統模式](https://www.easyweb.vip/doc/#/?id=_73-%e5%a4%9a%e7%b3%bb%e7%bb%9f%e6%a8%a1%e5%bc%8f)
??在header中有幾個選項:“xx系統”、“xx系統”,點擊不同的系統切換不同的側邊菜單,在線演示:[side-more.html](https://demo.easyweb.vip/iframe/page/template/side-more.html)
側邊欄代碼,使用`nav-id`標識不同的菜單:
~~~
<div class="layui-side">
<div class="layui-side-scroll">
<!-- 系統一的菜單,每個ul都加nav-id -->
<ul nav-id="xt1" class="layui-nav layui-nav-tree" lay-filter="admin-side-nav">
<!-- ...省略代碼... -->
</ul>
<!-- 系統二的菜單,加layui-hide隱藏 -->
<ul nav-id="xt2" class="layui-nav layui-nav-tree layui-hide" lay-filter="admin-side-nav">
<!-- ...省略代碼... -->
</ul>
</div>
</div>
~~~
header.html代碼,使用`nav-bind`綁定側邊欄菜單:
~~~
<div class="layui-header">
<ul class="layui-nav layui-layout-left">
<li class="layui-nav-item"><a nav-bind="xt1">系統一</a></li>
<li class="layui-nav-item"<a nav-bind="xt2">系統二</a></li>
</ul>
</div>
~~~
### [7.4 彈窗下拉框出現滾動條](https://www.easyweb.vip/doc/#/?id=_74-%e5%bc%b9%e7%aa%97%e4%b8%8b%e6%8b%89%e6%a1%86%e5%87%ba%e7%8e%b0%e6%bb%9a%e5%8a%a8%e6%9d%a1)
非iframe類型的彈窗才能解決,解決辦法如下:
~~~
admin.open({
title: '添加用戶',
content: $('#model').html(),
success: function (layero, index) {
// 禁止出現滾動條
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
});
~~~
> 關鍵代碼就是在success回調中寫上面那句話
### [7.5 彈窗寬度不能超出屏幕](https://www.easyweb.vip/doc/#/?id=_75-%e5%bc%b9%e7%aa%97%e5%ae%bd%e5%ba%a6%e4%b8%8d%e8%83%bd%e8%b6%85%e5%87%ba%e5%b1%8f%e5%b9%95)
?這個是針對手機屏幕下做了讓彈窗寬度自適應,如果你需要讓彈窗寬度超出屏幕如下代碼即可:
~~~
admin.open({
title: '添加用戶',
content: $('#model').html(),
success: function (layero, index) {
$(layero).css('max-width', 'unset'); // 去掉max-width屬性
}
});
~~~
> success回調中去掉max-width屬性
### [7.6 表單文字出現換行](https://www.easyweb.vip/doc/#/?id=_76-%e8%a1%a8%e5%8d%95%e6%96%87%e5%ad%97%e5%87%ba%e7%8e%b0%e6%8d%a2%e8%a1%8c)
?layui的表單左邊的標題文字最多顯示5個字,超出會換行,通過添加css修改寬度:
~~~
#userForm .layui-form-label {
width: 100px; // 這里修改標題寬度
}
#userForm .layui-input-block {
margin-left: 130px; // 這里要比上面始終大30px
}
~~~
?`#userForm`是表單的id,加id避免影響其他表單樣式:
~~~
<form id="userForm" class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">活動起止時間</label>
<div class="layui-input-block">
<input type="text" class="layui-input"/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">活動詳細介紹</label>
<div class="layui-input-block">
<textarea class="layui-textarea" maxlength="200"></textarea>
</div>
</div>
</form>
~~~
### [7.7 側邊欄折疊圖標放大](https://www.easyweb.vip/doc/#/?id=_77-%e4%be%a7%e8%be%b9%e6%a0%8f%e6%8a%98%e5%8f%a0%e5%9b%be%e6%a0%87%e6%94%be%e5%a4%a7)
?側邊欄折疊后圖標會進行放大,如果要修改大小,添加如下css:
~~~
@media screen and (min-width: 750px) {
.layui-layout-admin.admin-nav-mini .layui-side .layui-nav .layui-nav-item > a > .layui-icon {
font-size: 18px;
}
}
~~~
?修改font-size即可,如果不想放大,改成14px即可。
## [8.表單彈窗專題](https://www.easyweb.vip/doc/#/?id=_8%e8%a1%a8%e5%8d%95%e5%bc%b9%e7%aa%97%e4%b8%93%e9%a2%98)
??layui沒有像bootstrap那樣的直接寫在頁面中的模態彈窗,layui的彈窗是通過layer模塊用js去彈出窗口, 這就意味著layui的彈窗功能更豐富、操作更靈活,當然靈活也就意味著對于新手來說使用更為復雜, easyweb為了方便大家使用彈窗,也下了大量的功夫來封裝layer,下面來介紹在easyweb中使用彈窗的幾種方式。
### [8.1.第一種 頁面層彈窗](https://www.easyweb.vip/doc/#/?id=_81%e7%ac%ac%e4%b8%80%e7%a7%8d-%e9%a1%b5%e9%9d%a2%e5%b1%82%e5%bc%b9%e7%aa%97)
?頁面層彈窗就是彈窗頁面和列表頁面寫在一起,彈窗類型type=1:
~~~
<button id="btnAddUser" class="layui-btn">添加</button>
<table id="tableUser" lay-filter="tableUser"></table>
<!-- 表單彈窗 -->
<script type="text/html" id="modelUser">
<form id="modelUserForm" lay-filter="modelUserForm" class="layui-form model-form">
<input name="userId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">用戶名</label>
<div class="layui-input-block">
<input name="nickName" placeholder="請輸入用戶名" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性別</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男" checked/>
<input type="radio" name="sex" value="女" title="女"/>
</div>
</div>
<div class="layui-form-item text-right">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="modelSubmitUser" lay-submit>保存</button>
</div>
</form>
</script>
<!-- 表格操作列 -->
<script type="text/html" id="tableBarUser">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>
</script>
<!-- js部分 -->
<script>
layui.use(['layer', 'form', 'table', 'admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var table = layui.table;
var admin = layui.admin;
// 渲染表格
var insTb = table.render({
elem: '#tableUser',
url: '../../json/user.json',
cols: [[
{type: 'numbers', title: '#'},
{field: 'nickName', sort: true, title: '用戶名'},
{field: 'sex', sort: true, title: '性別'},
{align: 'center', toolbar: '#tableBarUser', title: '操作', minWidth: 200}
]]
});
// 添加
$('#btnAddUser').click(function () {
showEditModel();
});
// 工具條點擊事件
table.on('tool(tableUser)', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') { // 修改
showEditModel(data);
} else if (layEvent === 'del') { // 刪除
layer.msg('點擊了刪除', {icon: 2});
}
});
// 顯示表單彈窗
function showEditModel(mUser) {
admin.open({
type: 1,
title: (mUser ? '修改' : '添加') + '用戶',
content: $('#modelUser').html(),
success: function (layero, dIndex) {
var url = mUser ? '/updateUser' : '/addUser';
// 回顯數據
form.val('modelUserForm', mUser);
// 表單提交事件
form.on('submit(modelSubmitUser)', function (data) {
layer.load(2);
$.post(url, data.field, function (res) {
layer.closeAll('loading');
if (res.code == 200) {
layer.close(dIndex);
layer.msg(res.msg, {icon: 1});
insTb.reload();
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'json');
return false;
});
}
});
}
});
</script>
~~~
?彈窗的參數`type: 1`表示彈窗類型是頁面層類型而不是iframe層類型,`content: $("#modelUser").html()`是指定彈窗的內容, 表單使用`<script type="text/html">`而不是使用div,這樣表單頁面不會直接顯示在列表下面,需要注意的是,操作表單的代碼, 包括表單的事件監聽都要寫在彈窗的`success`回調里面,因為layer彈窗是把表單的html**復制一份**動態插入到頁面上,而不是把那一段代碼變成模態窗, 所以事件綁定必須寫在success里面。
> 這種方式表單和表格在一個頁面上面,數據傳遞、頁面相互操作比較方便,不涉及到iframe父子傳值的問題,推薦新手使用這種方式
### [8.2.第二種 iframe層彈窗](https://www.easyweb.vip/doc/#/?id=_82%e7%ac%ac%e4%ba%8c%e7%a7%8d-iframe%e5%b1%82%e5%bc%b9%e7%aa%97)
?使用iframe類型的彈窗可以讓表單頁面和表格頁面分開,邏輯更清晰。
彈窗頁面,userForm.html:
~~~
<html>
<head>
<link rel="stylesheet" href="../../assets/libs/layui/css/layui.css"/>
<link rel="stylesheet" href="../../assets/module/admin.css"/>
</head>
<body>
<form id="modelUserForm" lay-filter="modelUserForm" class="layui-form model-form">
<input name="userId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">用戶名</label>
<div class="layui-input-block">
<input name="nickName" placeholder="請輸入用戶名" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性別</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男" checked/>
<input type="radio" name="sex" value="女" title="女"/>
</div>
</div>
<div class="layui-form-item text-right">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="modelSubmitUser" lay-submit>保存</button>
</div>
</form>
<!-- js部分 -->
<script type="text/javascript" src="../../assets/libs/layui/layui.js"></script>
<script type="text/javascript" src="../../assets/js/common.js"></script>
<script>
layui.use(['layer', 'form', 'admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var mUser = parent.mSelUser; // 獲取列表頁面傳遞的數據,也可以使用top.xxx
// 回顯數據
form.val('modelUserForm', mUser);
// 表單提交事件
form.on('submit(modelSubmitUser)', function (data) {
layer.load(2);
var url = mUser ? '/updateUser' : '/addUser';
$.post(url, data.field, function (res) {
layer.closeAll('loading');
if (res.code == 200) {
layer.msg(res.msg, {icon: 1});
parent.userFormIsOk = true; // 設置操作成功的標識,也可以使用top.xxx
admin.closeThisDialog(); // 關閉當前iframe彈窗
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'json');
return false;
});
});
</script>
</body>
</html>
~~~
表格頁面,list.html:
~~~
<button id="btnAddUser" class="layui-btn">添加</button>
<table id="tableUser" lay-filter="tableUser"></table>
<!-- 表格操作列 -->
<script type="text/html" id="tableBarUser">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>
</script>
<!-- js部分 -->
<script>
layui.use(['layer', 'table', 'admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var table = layui.table;
var admin = layui.admin;
// 渲染表格
var insTb = table.render({
elem: '#tableUser',
url: '../../json/user.json',
cols: [[
{type: 'numbers', title: '#'},
{field: 'nickName', sort: true, title: '用戶名'},
{field: 'sex', sort: true, title: '性別'},
{align: 'center', toolbar: '#tableBarUser', title: '操作', minWidth: 200}
]]
});
// 添加
$('#btnAddUser').click(function () {
showEditModel();
});
// 工具條點擊事件
table.on('tool(tableUser)', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') { // 修改
showEditModel(data);
} else if (layEvent === 'del') { // 刪除
layer.msg('點擊了刪除', {icon: 2});
}
});
// 顯示表單彈窗
function showEditModel(mUser) {
window.mSelUser = mUser; // 傳遞數據到表單頁面,也可以使用top.xxx
window.userFormIsOk = false; // 重置表單操作成功標識,也可以使用top.xxx
admin.open({
type: 2,
title: (mUser ? '修改' : '添加') + '用戶',
content: 'userForm.html',
end: function () {
if (window.userFormIsOk) { // 判斷表單操作成功標識,也可以使用top.xxx
insTb.reload(); // 成功刷新表格
}
}
});
}
});
</script>
~~~
?彈窗參數`type: 2`就表示是一個iframe類型的彈窗,content參數寫表單的頁面url, 然后在end回調里面判斷操作成功的標識然后刷新表格,注意是end而不是success,這樣做的好處就是, 彈窗頁面跟表格獨立開了,大大減少了每個頁面的代碼量,將業務邏輯分開,壞處就是需要借助window和parent來做父子頁面的參數傳遞, 還有一個壞處就是,如果頁面有下拉框、日期選擇控件等元素,它們的范圍不能超出彈窗的范圍,會導致彈窗出現滾動條,甚至不顯示出來。
?那么有沒有辦法既能讓表單頁面獨立,又能讓表單里面的下拉框、日期等組件能夠超出彈窗的范圍呢,請看第三種方式。
?這里演示的是使用window和parent來傳遞參數,也可以使用admin.putTempData(key, value) 和admin.getTempData(key)來操作sessionStorage實現參數傳遞,如果你被window、parent、top這三個繞暈了,那就使用這個方法。
> 注意:如果你用top.layui.admin.open打開彈窗,那就不要用window和parent傳遞參數,全部使用top
### [8.3.第三種 url方式彈窗](https://www.easyweb.vip/doc/#/?id=_83%e7%ac%ac%e4%b8%89%e7%a7%8d-url%e6%96%b9%e5%bc%8f%e5%bc%b9%e7%aa%97)
?url方式彈窗就是使用url參數將彈窗頁面獨立出來:
彈窗頁面,userForm.html:
~~~
<form id="modelUserForm" lay-filter="modelUserForm" class="layui-form model-form">
<input name="userId" type="hidden"/>
<div class="layui-form-item">
<label class="layui-form-label">用戶名</label>
<div class="layui-input-block">
<input name="nickName" placeholder="請輸入用戶名" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性別</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男" checked/>
<input type="radio" name="sex" value="女" title="女"/>
</div>
</div>
<div class="layui-form-item text-right">
<button class="layui-btn layui-btn-primary" type="button" ew-event="closePageDialog">取消</button>
<button class="layui-btn" lay-filter="modelSubmitUser" lay-submit>保存</button>
</div>
</form>
<script>
layui.use(['layer', 'form', admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var mUser = window.mSelUser; // 列表頁面傳遞的數據,也可以使用top.xxx
// 回顯數據
form.val('modelUserForm', mUser);
// 表單提交事件
form.on('submit(modelSubmitUser)', function (data) {
layer.load(2);
var url = mUser ? '/updateUser' : '/addUser';
$.post(url, data.field, function (res) {
layer.closeAll('loading');
if (res.code == 200) {
layer.msg(res.msg, {icon: 1});
window.userFormIsOk = true; // 設置操作成功的標識,也可以使用top.xxx
admin.closeDialog('#modelUserForm'); // 關閉頁面層彈窗
} else {
layer.msg(res.msg, {icon: 2});
}
}, 'json');
return false;
});
});
</script>
~~~
?注意這里,頁面不需要寫`<html><body>`這些東西,它是一個html片段,不是完整的html頁面。
表格頁面,list.html:
~~~
<button id="btnAddUser" class="layui-btn">添加</button>
<table id="tableUser" lay-filter="tableUser"></table>
<!-- 表格操作列 -->
<script type="text/html" id="tableBarUser">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">刪除</a>
</script>
<!-- js部分 -->
<script>
layui.use(['layer', table', 'admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var table = layui.table;
var admin = layui.admin;
// 渲染表格
var insTb = table.render({
elem: '#tableUser',
url: '../../json/user.json',
cols: [[
{type: 'numbers', title: '#'},
{field: 'nickName', sort: true, title: '用戶名'},
{field: 'sex', sort: true, title: '性別'},
{align: 'center', toolbar: '#tableBarUser', title: '操作', minWidth: 200}
]]
});
// 添加
$('#btnAddUser').click(function () {
showEditModel();
});
// 工具條點擊事件
table.on('tool(tableUser)', function (obj) {
var data = obj.data;
var layEvent = obj.event;
if (layEvent === 'edit') { // 修改
showEditModel(data);
} else if (layEvent === 'del') { // 刪除
layer.msg('點擊了刪除', {icon: 2});
}
});
// 顯示表單彈窗
function showEditModel(mUser) {
window.mSelUser = mUser; // 傳遞數據到表單頁面,也可以使用top.xxx
window.userFormIsOk = false; // 重置表單操作成功標識,也可以使用top.xxx
admin.open({
title: (mUser ? '修改' : '添加') + '用戶',
url: 'userForm.html',
end: function () {
if (window.userFormIsOk) { // 判斷表單操作成功標識,也可以使用top.xxx
insTb.reload();
}
},
success: function (layero, dIndex) {
// 彈窗超出范圍不出現滾動條
$(layero).children('.layui-layer-content').css('overflow', 'visible');
}
});
}
});
</script>
~~~
?這里與iframe彈窗的區別是,使用`url`參數指定表單的頁面鏈接,而不是使用content,url這個參數是admin.open擴展的,layer不具備, 這樣做會把表單頁面的html內容使用ajax加載到彈窗中,而不是iframe嵌入,這樣表單里面的下拉框、日期等組件就可以超出彈窗的范圍,不會導致彈窗出現滾動條。
?需要注意的是,參數傳遞不是widnow和parent,而是全部是window,因為表單頁面和列表頁面雖然是兩個頁面,但是是通過ajax加載在一個頁面上的 ,如果使用top.layui.admin.open打開彈窗那就全部使用top。
> 注意:表單頁面是html片段,不是完整的html,這點不要忘記了,另外表單頁面和表格頁面不要出現重復的id,因為最終是在一個頁面上
### [8.4.三種方式選擇指南](https://www.easyweb.vip/doc/#/?id=_84%e4%b8%89%e7%a7%8d%e6%96%b9%e5%bc%8f%e9%80%89%e6%8b%a9%e6%8c%87%e5%8d%97)
| 方式 | 推薦 | 理由 |
| :-- | :-- | :-- |
| 第一種 | 建議新手使用這種 | 不涉及兩個頁面傳值問題 |
| 第二種 | 推薦表單跟表格無交互使用,比如詳情 | iframe彈窗不建議做表單 |
| 第三種 | 表單彈窗、頁面有交互建議使用 | 頁面傳值方便,不存在問題 |
?父子頁面參數傳遞除了使用window、parent、top之外,還可以使用admin.putTempData(key, value) 和admin.getTempData(key)來操作sessionStorage實現參數傳遞,如果你被window、parent、top這三個繞暈了, 那就使用這個方法,這個方法是操作本地存儲sessionStorage,從效率上來講沒有window和parent高效。
### [8.5.admin.modelForm方法](https://www.easyweb.vip/doc/#/?id=_85adminmodelform%e6%96%b9%e6%b3%95)
?此方法是把layer彈窗自帶的確定按鈕綁定成表單的提交按鈕。
~~~
<!-- 表單彈窗 -->
<script type="text/html" id="modelUser">
<div class="layui-form-item">
<label class="layui-form-label">用戶名</label>
<div class="layui-input-block">
<input name="nickName" placeholder="請輸入用戶名" type="text" class="layui-input" maxlength="20"
lay-verType="tips" lay-verify="required" required/>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性別</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男" checked/>
<input type="radio" name="sex" value="女" title="女"/>
</div>
</div>
</script>
<!-- js部分 -->
<script>
layui.use(['layer', 'form', admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
admin.open({
type: 1,
title: '添加用戶',
btn: ['確定', '取消'],
content: $('#modelUser').html(),
success: function (layero, dIndex) {
// 把確定按鈕綁定表單提交,參數二是給按鈕起一個lay-filter,參數三是給表單起一個lay-filter
admin.modelForm(layero, 'demoFormSubmit', 'demoForm');
// 給表單賦值
form.val('demoForm', {nickName: '張三', sex: '男'});
// 監聽表單提交
form.on('submit(demoFormSubmit)', function (data) {
layer.msg(JSON.stringify(data.field));
return false;
});
},
yes: function () {
// 確定按鈕方法什么都不要操作
}
});
});
</script>
~~~
?admin.modelForm()這個方法會把彈窗外面包一個form,然后把確定按鈕加lay-submit,所以你的表單頁面不需要寫form和確定、關閉按鈕,只需要寫表單項。
?這個方法的使用場景為你想要表單的按鈕固定,只滾動表單內容部分,可以用這個操作, 當然以前那種表單彈窗的寫法(就是自己寫確定和取消按鈕那種寫法)也是支持固定按鈕的, 前面css組件樣式中有介紹。