首次使用layui开发总结
一、layui官方文档
二、布局
栅格系统
为了丰富网页布局,简化 HTML/CSS 代码的耦合,并提升多终端的适配能力,layui 在 2.0 的版本中引进了自己的一套具备响应式能力的栅格系统。我们将容器进行了 12 等分,预设了 4*12 种 CSS 排列类,它们在移动设备、平板、桌面中/大尺寸四种不同的屏幕下发挥着各自的作用。
(一)、栅格布局规则:
序号 | |
---|---|
1 | 采用 layui-row 来定义行,如:<div class="layui-row"></div> |
2 | 采用类似 layui-col-md* 这样的预设类来定义一组列(column),且放在行(row)内。其中: 1. 变量 md 代表的是不同屏幕下的标记(可选值见下文)2. 变量 * 代表的是该列所占用的12等分数 (如6/12),可选值为 1 - 12 3. 如果多个列的 “等分数值”总和等于12 ,则刚好满行排列。如果大于12,多余的列将自动另起一行。 |
3 | 列可以同时出现最多四种不同的组合,分别是:xs (超小屏幕,如手机)、sm (小屏幕,如平板)、md (桌面中等屏幕)、lg (桌面大型屏幕),以呈现更加动态灵活的布局。 |
4 | 可对列追加类似layui-col-space5、 layui-col-md-offset3 这样的预设类来定义列的间距 和偏移 。 |
5 | 最后,在列(column)元素中放入你自己的任意元素填充内容,完成布局! |
<div class="layui-container">
常规布局(以中型屏幕桌面为例):
<div class="layui-row">
<div class="layui-col-md9">
你的内容 9/12
</div>
<div class="layui-col-md3">
你的内容 3/12
</div>
</div>
移动设备、平板、桌面端的不同表现:
<div class="layui-row">
<div class="layui-col-xs6 layui-col-sm6 layui-col-md4">
移动:6/12 | 平板:6/12 | 桌面:4/12
</div>
<div class="layui-col-xs6 layui-col-sm6 layui-col-md4">
移动:6/12 | 平板:6/12 | 桌面:4/12
</div>
<div class="layui-col-xs4 layui-col-sm12 layui-col-md4">
移动:4/12 | 平板:12/12 | 桌面:4/12
</div>
<div class="layui-col-xs4 layui-col-sm7 layui-col-md8">
移动:4/12 | 平板:7/12 | 桌面:8/12
</div>
<div class="layui-col-xs4 layui-col-sm5 layui-col-md4">
移动:4/12 | 平板:5/12 | 桌面:4/12
</div>
</div>
</div>
(二)、响应式规则:
栅格的响应式能力,得益于CSS3媒体查询(Media Queries)的强力支持,从而针对四类不同尺寸的屏幕,进行相应的适配处理
超小屏幕(手机<768px) | 小屏幕(平板≥768px) | 中等屏幕(桌面≥992px) | 大型屏幕(桌面≥1200px) | |
---|---|---|---|---|
.layui-container的值 | auto | 750px | 970px | 1170px |
标记 | xs | sm | md | lg |
列对应类* 为1-12的等分数值 | layui-col-xs* | layui-col-sm* | layui-col-md* | layui-col-lg* |
总列数 | 12 | 12 | 12 | 12 |
响应行为 | 始终按设定的比例水平排列 | 在当前屏幕下水平排列,如果屏幕大小低于临界值则堆叠排列 | 在当前屏幕下水平排列,如果屏幕大小低于临界值则堆叠排列 | 在当前屏幕下水平排列,如果屏幕大小低于临界值则堆叠排列 |
(三)、响应式公共类:
类名(class) | 说明 |
---|---|
layui-show-*-block | 定义不同设备下的 display: block; * 可选值有:xs、sm、md、lg |
layui-show-*-inline | 定义不同设备下的 display: inline; * 可选值同上 |
layui-show-*-inline-block | 定义不同设备下的 display: inline-block; * 可选值同上 |
layui-hide-* | 定义不同设备下的隐藏类,即: display: none; * 可选值同上 |
(四)、布局容器:
将栅格放入一个带有 class=“layui-container” 的特定的容器中,以便在小屏幕以上的设备中固定宽度,让列可控。
</>code
<div class="layui-container">
<div class="layui-row">
……
</div>
</div>
当然,你还可以不固定容器宽度。将栅格或其它元素放入一个带有 class=“layui-fluid” 的容器中,那么宽度将不会固定,而是 100% 适应
<div class="layui-fluid">
……
</div>
(五)、列间距:
通过“列间距”的预设类,来设定列之间的间距。且一行中最左的列不会出现左边距,最右的列不会出现右边距。列间距在保证排版美观的同时,还可以进一步保证分列的宽度精细程度。我们结合网页常用的边距,预设了 12 种不同尺寸的边距,分别是:
列间距 | 内容 |
---|---|
layui-col-space1 layui-col-space2 … layui-col-space28 layui-col-space30 | 支持列之间为 1px-30px 区间的所有双数间隔,以及 1px、5px、15px、25px 的单数间隔 |
简单的例子,列间距为10px:
<div class="layui-row layui-col-space10">
<div class="layui-col-md4">
1/3
</div>
<div class="layui-col-md4">
1/3
</div>
<div class="layui-col-md4">
1/3
</div>
</div>
如果需要的间距高于30px(一般不常见),请采用偏移,下文继续讲解
(六)、列偏移:
对列追加 类似 layui-col-md-offset* 的预设类,从而让列向右偏移。其中 * 号代表的是偏移占据的列数,可选中为 1 - 12。
如:layui-col-md-offset3,即代表在“中型桌面屏幕”下,让该列向右偏移 3 个列宽度
下面是一个采用「列偏移」机制让两个列左右对齐的实例
请注意,列偏移可针对不同屏幕的标准进行设定,比如上述的例子,只会在桌面屏幕下有效,当低于桌面屏幕的规定的临界值,就会堆叠排列。
<div class="layui-row">
<div class="layui-col-md4">
4/12
</div>
<div class="layui-col-md4 layui-col-md-offset4">
偏移4列,从而在最右
</div>
</div>
(七)、栅格嵌套:
理论上,你可以对栅格进行无穷层次的嵌套,这更加增强了栅格的表现能力。而嵌套的使用非常简单。在列元素(layui-col-md*)中插入一个行元素(layui-row),即可完成嵌套。下面是一个简单的例子:
<div class="layui-row layui-col-space5">
<div class="layui-col-md5">
<div class="layui-row grid-demo">
<div class="layui-col-md3">
内部列
</div>
<div class="layui-col-md9">
内部列
</div>
<div class="layui-col-md12">
内部列
</div>
</div>
</div>
<div class="layui-col-md7">
<div class="layui-row grid-demo grid-demo-bg1">
<div class="layui-col-md12">
内部列
</div>
<div class="layui-col-md9">
内部列
</div>
<div class="layui-col-md3">
内部列
</div>
</div>
</div>
</div>
(八)、让IE8/9兼容栅格:
事实上IE8和IE9并不支持媒体查询(Media Queries),但你可以使用下面的补丁完美兼容!该补丁来自于开源社区:
<!-- 让IE8/9支持媒体查询,从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
管理系统界面布局
layui 之所以赢得如此多人的青睐,更多是在于它「前后界面兼备」的能力。既可编织出绚丽的前台页面,又可满足繁杂的管理系统界面需求。layui 致力于让每一位开发者都能轻松搭建自己的管理界面。下面是演示代码,你可以前往示例页面: 预览布局效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>layout 管理系统大布局 - Layui</title>
<link rel="stylesheet" href="./layui/css/layui.css">
</head>
<body>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div>
<!-- 头部区域(可配合layui 已有的水平导航) -->
<ul class="layui-nav layui-layout-left">
<!-- 移动端显示 -->
<li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
<i class="layui-icon layui-icon-spread-left"></i>
</li>
<li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li>
<li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li>
<li class="layui-nav-item">
<a href="javascript:;">nav groups</a>
<dl class="layui-nav-child">
<dd><a href="">menu 11</a></dd>
<dd><a href="">menu 22</a></dd>
<dd><a href="">menu 33</a></dd>
</dl>
</li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
<a href="javascript:;">
<img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
tester
</a>
<dl class="layui-nav-child">
<dd><a href="">Your Profile</a></dd>
<dd><a href="">Settings</a></dd>
<dd><a href="">Sign out</a></dd>
</dl>
</li>
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
<a href="javascript:;">
<i class="layui-icon layui-icon-more-vertical"></i>
</a>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<li class="layui-nav-item layui-nav-itemed">
<a class="" href="javascript:;">menu group 1</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">menu 1</a></dd>
<dd><a href="javascript:;">menu 2</a></dd>
<dd><a href="javascript:;">menu 3</a></dd>
<dd><a href="">the links</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="javascript:;">menu group 2</a>
<dl class="layui-nav-child">
<dd><a href="javascript:;">list 1</a></dd>
<dd><a href="javascript:;">list 2</a></dd>
<dd><a href="">超链接</a></dd>
</dl>
</li>
<li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
<li class="layui-nav-item"><a href="">the links</a></li>
</ul>
</div>
</div>
<div class="layui-body">
<!-- 内容主体区域 -->
<div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
</div>
<div class="layui-footer">
<!-- 底部固定区域 -->
底部固定区域
</div>
</div>
<script src="./layui/layui.js"></script>
<script>
//JS
layui.use(['element', 'layer', 'util'], function(){
var element = layui.element
,layer = layui.layer
,util = layui.util
,$ = layui.$;
//头部事件
util.event('lay-header-event', {
//左侧菜单事件
menuLeft: function(othis){
layer.msg('展开左侧菜单的操作', {icon: 0});
}
,menuRight: function(){
layer.open({
type: 1
,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
,area: ['260px', '100%']
,offset: 'rt' //右上角
,anim: 5
,shadeClose: true
});
}
});
});
</script>
</body>
</html>
三、样式
(一)、 文本样式
1. 对溢出文本显示省略号
解释:
- overflow: hidden; // 超出的文本隐藏
- text-overflow: ellipsis; // 溢出用省略号显示
- white-space: nowrap; // 溢出不换行
- display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示。
- -webkit-line-clamp: 2; // 这个属性不是css的规范属性,需要组合上面两个属性,表示显示的行数。
- -webkit-box-orient: vertical; // 从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
- -o-text-overflow:ellipsis;
- width:100%;
其中overflow: hidden和white-space: nowrap都是必须的否则不会显示省略号;-o-text-overflow: ellipsis针对Opera;而宽度的设定主要是针对IE6;
该方法支持Internet Explorer, Safari, Chrome 和 Opera,但FF
并不支持,可以通过Jquery来实现类似的效果。
下载这个Jquery插件:jQuery ellipsis plugin
调用方法:
$(document).ready(function() {
$('.ellipsis').ellipsis();
}
内容省略两个好处
- 一是不用通过程序限定字数;
- 二是有利于SEO。需要使用对对溢出文本显示省略号的通常是文章标题列表,这样处理对搜索引擎更友好,因为标题实际上并未被截字,而是局限于宽度而未被显示而已。
1.1 超出隐藏并使用省略号
<div class="layui-text" style="font-family:黑体;overflow:hidden; white-space:nowrap;
text-overflow:ellipsis;width:100%;">
需要展示的内容需要展示的内容需要展示的内容需要展示的内容需要展示的内容
</div>
1.2 规定超出行数
overflow: hidden;
display: -webkit-box; // 将对象作为弹性伸缩盒子模型显示
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
text-overflow: ellipsis; // 从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)
问题:代码经过编译后就把-webkit-box-orient: vertical干掉了
解决方案一:
/* autoprefixer: off*/
-webkit-box-orient: vertical;
/* autoprefixer: on*/
这样确实解决了编译丢失的情况,但会在编译过程中报warning
最佳解决方案,如下
/* autoprefixer: ignore next */
-webkit-box-orient: vertical;
解决方案二:
将-webkit-box-orient: vertical样式直接内联在HTML标签内
解决方案三:
编译后就把-webkit-box-orient: vertical干掉,是编译过程导致这个属性丢失,optimize-css-assets-webpack-plugin这个插件的影响,在查问题的时候发现有人这样解决,未验证(点击查看原文链接)。注释掉webpack.prod.conf.js中下面的代码
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
(二)、表格样式
1. layui表头和内容不能对齐问题
表格页面css:
.layui-card .layui-card-body .layui-table td { max-width: 100%;}
th.layui-table-patch{padding: 0 !important;}
// display: table-caption;此元素会作为一个表格标题来显示,类似于 <caption> 水平、垂直居中
.layui-table-cell{display: table-caption;}
表格数据渲染js:
function tableRender(data) {
var maxTbHigh = data.length * 41 > tableHight ? tableHight : undefined;
dataTable.render({
elem: '#resultData'
, data: data
, cellMinWidth: 60
, skin: 'line'
, page: true
, size: 'dm'
, id: 'rowIndex'
, limit: 10
, height: maxTbHigh
, cols: [[
{field: 'No', title: '序号', templet: '#index',width: '4%',align: 'center'},//,
{
field: 'DOC_NAME', title: '文档名称',width: '28%',align: 'center',
templet: function (data) {
return data.docName;
}
},
{
field: 'DOC_TYPE', title: '文档类型',width: '8%',align: 'center',
templet: function (data) {
return data.docType;
}
}
]],
- 表格内容不多的情况
当内容不多的时候或者表格列比较少的时候,layui默认的最大单元格宽度是400px
,这时候就会出现无法对齐的情况。此时只需要去掉最大宽度限制即可
.layui-card .layui-card-body .layui-table td { max-width: 100%;}
-
设置的宽度总和不足100%的情况
这种情况比较好处理,但是还有一种情况就是,总宽度减去其他设置宽度的总和剩下的宽度仍然超出400px的情况,这种情况也会造成无法对齐, -
逗号问题,因为layui的喜欢把逗号写前面,所以需要自己注意一下
-
内容太多出现滚动条的情况,这时候我们可以试着处理一下,单元格的左右间距
th.layui-table-patch{padding: 0 !important;}
同理行高也有限制的,最大不能超出80px
2. 表格自增序号展示
表格序号html:
<script type="text/html" id="index">
{{d.LAY_TABLE_INDEX+1}}
</script>
表格序号js:
function tableRender(data) {
var maxTbHigh = data.length * 41 > tableHight ? tableHight : undefined;
dataTable.render({
elem: '#resultData'
, data: data
, cellMinWidth: 60
, skin: 'line'
, page: true
, size: 'dm'
, id: 'rowIndex'
, limit: 10
, height: maxTbHigh
, cols: [[
{field: 'No', title: '序号', fixed: 'left', templet: '#index', width: '4%', align: 'center'}
]]
})
}
3. 获取表格选中行当前行数据
表格当前行索引及数据获取js:
function tableRender(data) {
var maxTbHigh = data.length * 41 > tableHight ? tableHight : undefined;
dataTable.render({
elem: '#resultData'
, data: data
, id: 'rowIndex'
,...
})
}
//获取选中行数据
var checkStatus = dataTable.checkStatus('rowIndex')
var origData = checkStatus.data
var userName = origData[0].userName // 获取当前选中行用户姓名
4. 绑定行点击事件和获取行数据的方法
4.1 绑定tr
行点击事件
layui中,给了监听方法,并且还可以获取到该行所有的数据;
相关的html:
<table class="layui-table " id="listTable" lay-filter="test"
cellpadding="0" cellspacing="0">
</table>
// 第一种方法
done: function(res, curr, count){
$('#div').find('.layui-table-body').find("table" ).find("tbody").children("tr").on('click',function(){
var id = JSON.stringify($('#div').find('.layui-table-body').find("table" ).find("tbody").find(".layui-table-hover").data('index'));
var obj = res.data[id]; //这里都是表格的数据
fun.openLayer(obj);
})
}
// 第二种方法 监听tr(行点击事件)如下:需要给table设置layui-filter
table.on('row(test)',function(obj){
console.log(obj)
})
4.2 绑定td
行点击事件
相关的html:
<table class="layui-table " id="listTable" lay-filter="test"
cellpadding="0" cellspacing="0">
</table>
监听td事件的话,我们需要在cols中添加event事件:
function tableRender(data) {
dataTable.render({
elem: '#table'
, btns: ['clear', 'confirm']
, data: data
, id: 'rowIndex'
, ...
, cols: [[
{
field: 'MESSAGE_TITLE',
event: 'seepage',
title: '消息标题',
width: '50%',
align: 'center',
templet: function (data) {
return data.messageTitle;
}
}
]]
定义点击事件:'tool(test)'
dataTable.on('tool(test)', function (obj) {
let ev = obj.event;
if (ev == 'seepage') {
layer.open({
type: 1
//,title: false //不显示标题栏,
closeBtn: false,
area: ['80%', '70%'],
shade: 0.8,
id: 'LAY_layuipro' ,//设定一个id,防止重复弹出
btn: ['关闭'],
btnAlign: 'c',
moveType: 1 //拖拽模式,0或者1,
content: 'content' // 需要展示的内容,
yes: function (index, layer) {
$('#message').css('display', 'none')
layer.close(layer.index);
}
})
}
//console.log(obj.tr) //得到当前行元素对象
//console.log(obj.data) //得到当前行数据
//obj.del(); //删除当前行
//obj.update(fields) //修改当前行数据
});
(三)、弹窗样式
1. layer.open()的content属性传参数方法
type - 基本层类型
类型:Number,默认:0
layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)。 若你采用layer.open({type: 1})方式调用,则type为必填项(信息框除外)
content - 内容
类型:String/DOM/Array,默认:‘’
content可传入的值是灵活多变的,不仅可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同。譬如:
/!*
如果是页面层
*/
layer.open({
type: 1,
content: '传入任意的文本或html' //这里content是一个普通的String
});
layer.open({
type: 1,
content: $('#id') //这里content是一个DOM,注意:最好该元素要存放在body最外层,否则可能被其它的相对元素所影响
});
//Ajax获取
$.post('url', {}, function(str){
layer.open({
type: 1,
content: str //注意,如果str是object,那么需要字符拼接。
});
});
/!*
如果是iframe层
*/
layer.open({
type: 2,
content: 'http://sentsin.com' //这里content是一个URL,如果你不想让iframe出现滚动条,你还可以content: ['http://sentsin.com', 'no']
});
/!*
如果是用layer.open执行tips层
*/
layer.open({
type: 4,
content: ['内容', '#id'] //数组第二项即吸附元素选择器或者DOM
});
2. btn - 按钮点击事件
类型:String/Array,默认:‘确认’
信息框模式时,btn默认是一个确认按钮,其它层类型则默认不显示,加载层和tips层则无效。当您只想自定义一个按钮时,你可以btn: ‘我知道了’,当你要定义两个按钮时,你可以btn: [‘yes’, ‘no’]。当然,你也可以定义更多按钮,比如:btn: [‘按钮1’, ‘按钮2’, ‘按钮3’, …],按钮1的回调是yes,而从按钮2开始,则回调为btn2: function(){},以此类推。如:
//eg1
layer.confirm('纳尼?', {
btn: ['按钮一', '按钮二', '按钮三'] //可以无限个按钮
,btn3: function(index, layero){
//按钮【按钮三】的回调
}
}, function(index, layero){
//按钮【按钮一】的回调
}, function(index){
//按钮【按钮二】的回调
});
//eg2
layer.open({
content: 'test'
,btn: ['按钮一', '按钮二', '按钮三']
,yes: function(index, layero){
//按钮【按钮一】的回调
}
,btn2: function(index, layero){
//按钮【按钮二】的回调
//return false 开启该代码可禁止点击该按钮关闭
}
,btn3: function(index, layero){
//按钮【按钮三】的回调
//return false 开启该代码可禁止点击该按钮关闭
}
,cancel: function(){
//右上角关闭回调
//return false 开启该代码可禁止点击该按钮关闭
}
});
3. 弹窗中调用ajax请求
function myAjax (_data, _url, callBack) { //把原本的ajax封装一下,下次调用直接传地址、参数进行回调。例如:
var index = layer.open({
type: 1
, title: '修改文档'
, closeBtn: false
, area: '500px;'
, shade: 0.8
, id: 'LAY_layuipro' //设定一个id,防止重复弹出
, btn: ['确定', '取消']
, btnAlign: 'c'
, moveType: 1 //拖拽模式,0或者1
, content: $('#edit-main')
, btn2: function (index, layero) {
layer.close(index);
}
, yes: function (index, layero) {
editAjax(editRequest, function (data) {
layer.close(index); // 关闭弹窗
if (data === true) {
layer.open({
title: '提示'
, content: '修改成功'
});
} else if (data === false) {
layer.open({
title: '提示'
, content: '修改失败,请稍后再试!'
});
}
})
layer.close(index);
layer.open({
title: '提示'
, content: '修改成功'
});
}
}
});
// 定义一个ajax请求
function editAjax(_data, callBack) {
$.ajax({
type: "POST"
, url: "url" // 对接后端地址
, data: JSON.stringify(_data)
, contentType: "application/json;charset=utf-8"
, error: function (request) {
//...
}
, success: function (request) {
// ...
}
});
}
(四)、表单-页面元素样式
1. layui表单样式渲染
问题一
当动态修改过表单元素后,需要再一次进行表单渲染,否则修改不生效。
例如:
$('#statusCode').val('01') // 修改下拉框选中项,需要重新渲染。
//刷新select选择框渲染 必须要!这里的'select'不是选择器,是固定写法。
layui.form.render('select');
layui.form.render()//渲染表单