LayUI_03 前端框架 内置模块

目录

一、弹层组件文档 - layui.layer

作为独立组件使用 layercode

在 layui 中使用 layercode

二、日期和时间组件文档 - layui.laydate

在 layui 模块中使用code

作为独立组件使用code

三、分页模块文档 - layui.laypage

在 layui 模块中使用code

四、模板引擎文档 - layui.laytpl

五、table 数据表格文档 - layui.table

对应的代码code

HTMLcode

JavaScriptcode

code

HTMLcode

JavaScriptcode

六、表单模块文档 - layui.form

layui.form小例子code

七、图片/文件上传 - layui.upload

八、下拉菜单组件文档 - layui.dropdown

九、穿梭框组件文档 - layui.transfer

layui.transfer小例子code

code

合法的数据格式code

不符合规范的数据格式code

十、树形组件文档 - layui.tree

十一、颜色选择器文档 - layui.colorpicker

十二、常用元素操作 - layui.element

十三、滑块文档 - layui.slider

十四、评分组件文档 - layui.rate

layui.rate小例子code

十五、通用轮播组件文档 - layui.carousel

对应的代码code

十六、富文本编辑器文档 - layui.layedit

十七、流加载文档 - layui.flow

十八、工具集文档 - layui.util

十九、代码高亮文档 - layui.code


一、弹层组件文档 - layui.layer

layer 至今仍作为 layui 的代表作,它的受众广泛并非偶然,而是这数年来的坚持、不弃的执念,将那些不屑的眼光转化为应得的尊重,不断完善和维护、不断建设和提升社区服务,在 Web 开发者的圈子里口口相传,乃至于成为今天的 layui 最强劲的源动力。目前, layer 已然成为网页弹出层的首选交互方案,几乎随处可见。
模块加载名称: layer,独立版本: layer.layui.com

使用场景

由于layer可以独立使用,也可以通过Layui模块化使用。所以请按照你的实际需求来选择。

场景用前准备调用方式
1. 作为独立组件使用如果你只是单独想使用 layer,你可以去 layer 独立版本官网下载组件包。你需要在你的页面引入jQuery1.8以上的任意版本,并引入layer.js通过script标签引入layer.js后,直接用即可。 参考:快速上手
2. layui 模块化使用如果你使用的是 layui,那么你直接在官网下载 layui 框架即可,无需引入 jQuery 和 layer.js,但需要引入layui.csslayui.js通过layui.use('layer', callback)加载模块
 

作为独立组件使用 layercode

  1. 引入好layer.js后,直接用即可
    <script src="layer.js"></script>
    <script>
    layer.msg('hello');
    </script>

在 layui 中使用 layercode

layui.use('layer', function(){
var layer = layui.layer;

layer.msg('hello');
});

除了上面有所不同,其它都完全一致。

基础参数

我们提到的基础参数主要指调用方法时用到的配置项,如:layer.open({content: ''})layer.msg('', {time: 3})等,其中的content和time即是基础参数,以键值形式存在,基础参数可合理应用于任何层类型中,您不需要所有都去配置,大多数都是可选的。而其中的layer.open、layer.msg就是内置方法。注意,从2.3开始,无需通过layer.config来加载拓展模块

type - 基本层类型

title - 标题

content - 内容

skin - 样式类名

area - 宽高

offset - 坐标

icon - 图标。信息框和加载层的私有参数

btn - 按钮

btnAlign - 按钮排列

closeBtn - 关闭按钮

shade - 遮罩

shadeClose - 是否点击遮罩关闭

time - 自动关闭所需毫秒

id - 用于控制弹层唯一标识

anim - 弹出动画

备注
anim: 0平滑放大。默认
anim: 1从上掉落
anim: 2从最底部往上滑入
anim: 3从左滑入
anim: 4从左翻滚
anim: 5渐显
anim: 6抖动

isOutAnim - 关闭动画 (layer 3.0.3新增)

maxmin - 最大最小化。

fixed - 固定

resize - 是否允许拉伸

resizing - 监听窗口拉伸动作

scrollbar - 是否允许浏览器出现滚动条

maxWidth - 最大宽度

maxHeight - 最大高度

zIndex - 层叠顺序

move - 触发拖动的元素

moveOut - 是否允许拖拽到窗口外

moveEnd - 拖动完毕后的回调方法

tips - tips方向和颜色

tipsMore - 是否允许多个tips

success - 层弹出后的成功回调方法

yes - 确定按钮回调方法

cancel - 右上角关闭按钮触发的回调

end - 层销毁后触发的回调

full/min/restore -分别代表最大化、最小化、还原 后触发的回调

minStack - 是否默认堆叠在左下角

类型:Number,默认:0

layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)。 若你采用layer.open({type: 1})方式调用,则type为必填项(信息框除外)

类型:String/Array/Boolean,默认:'信息'

title支持三种类型的值,若你传入的是普通的字符串,如title :'我是标题',那么只会改变标题文本;若你还需要自定义标题区域样式,那么你可以title: ['文本', 'font-size:18px;'],数组第二项可以写任意css样式;如果你不想显示标题栏,你可以title: false

类型:String/DOM/Array,默认:''

content可传入的值是灵活多变的,不仅可以传入普通的html内容,还可以指定DOM,更可以随着type的不同而不同。譬如:

</>code

/!*
如果是页面层
*/
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
});

类型:String,默认:''

skin不仅允许你传入layer内置的样式class名,还可以传入您自定义的class名。这是一个很好的切入点,意味着你可以借助skin轻松完成不同的风格定制。目前layer内置的skin有:layui-layer-lanlayui-layer-molv,未来我们还会选择性地内置更多,但更推荐您自己来定义。以下是一个自定义风格的简单例子

 

</>code


//单个使用
layer.open({
skin: 'demo-class'
});
//全局使用。即所有弹出层都默认采用,但是单个配置skin的优先级更高
layer.config({
skin: 'demo-class'
})
//CSS
body .demo-class .layui-layer-title{background:#c00; color:#fff; border: none;}
body .demo-class .layui-layer-btn{border-top:1px solid #E9E7E7}
body .demo-class .layui-layer-btn a{background:#333;}
body .demo-class .layui-layer-btn .layui-layer-btn1{background:#999;}
…
  1. 加上body是为了保证优先级。你可以借助Chrome调试工具,定义更多样式控制层更多的区域。

你也可以去查看layer皮肤制作说明

类型:String/Array,默认:'auto'

在默认状态下,layer是宽高都自适应的,但当你只想定义宽度时,你可以area: '500px',高度仍然是自适应的。当你宽高都要定义时,你可以area: ['500px', '300px']

类型:String/Array,默认:垂直水平居中

offset默认情况下不用设置。但如果你不想垂直水平居中,你还可以进行以下赋值:

备注
offset: 'auto'默认坐标,即垂直水平居中
offset: '100px'只定义top坐标,水平保持居中
offset: ['100px', '50px']同时定义top、left坐标
offset: 't'快捷设置顶部坐标
offset: 'r'快捷设置右边缘坐标
offset: 'b'快捷设置底部坐标
offset: 'l'快捷设置左边缘坐标
offset: 'lt'快捷设置左上角
offset: 'lb'快捷设置左下角
offset: 'rt'快捷设置右上角
offset: 'rb'快捷设置右下角

类型:Number,默认:-1(信息框)/0(加载层)

信息框默认不显示图标。当你想显示图标时,默认皮肤可以传入0-6如果是加载层,可以传入0-2。如:

</>code

//eg1
layer.alert('酷毙了', {icon: 1});
//eg2
layer.msg('不开心。。', {icon: 5});
//eg3
layer.load(1); //风格1的加载

类型:String/Array,默认:'确认'

信息框模式时,btn默认是一个确认按钮,其它层类型则默认不显示,加载层和tips层则无效。当您只想自定义一个按钮时,你可以btn: '我知道了',当你要定义两个按钮时,你可以btn: ['yes', 'no']。当然,你也可以定义更多按钮,比如:btn: ['按钮1', '按钮2', '按钮3', …],按钮1的回调是yes,而从按钮2开始,则回调为btn2: function(){},以此类推。如:

 

</>code

//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 开启该代码可禁止点击该按钮关闭
}
});

类型:String,默认:r

你可以快捷定义按钮的排列位置,btnAlign的默认值为r,即右对齐。该参数可支持的赋值如下:

备注
btnAlign: 'l'按钮左对齐
btnAlign: 'c'按钮居中对齐
btnAlign: 'r'按钮右对齐。默认值,不用设置

类型:String/Boolean,默认:1

layer提供了两种风格的关闭按钮,可通过配置12来展示,如果不显示,则closeBtn: 0

类型:String/Array/Boolean,默认:0.3

即弹层外区域。默认是0.3透明度的黑色背景('#000')。如果你想定义别的颜色,可以shade: [0.8, '#393D49'];如果你不想显示遮罩,可以shade: 0

类型:Boolean,默认:false

如果你的shade是存在的,那么你可以设定shadeClose来控制点击弹层外区域关闭。

类型:Number,默认:0

默认不会自动关闭。当你想自动关闭时,可以time: 5000,即代表5秒后自动关闭,注意单位是毫秒(1秒=1000毫秒)

类型:String,默认:空字符

设置该值后,不管是什么类型的层,都只允许同时弹出一个。一般用于页面层和iframe层模式

类型:Number,默认:0

我们的出场动画全部采用CSS3。这意味着除了ie6-9,其它所有浏览器都是支持的。目前anim可支持的动画类型有0-6 如果不想显示动画,设置 anim: -1 即可。另外需要注意的是,3.0之前的版本用的是 shift 参数

类型:Boolean,默认:true

默认情况下,关闭层时会有一个过度动画。如果你不想开启,设置 isOutAnim: false 即可

类型:Boolean,默认:false

该参数值对type:1type:2有效。默认不显示最大小化按钮。需要显示配置maxmin: true即可

类型:Boolean,默认:true

即鼠标滚动时,层是否固定在可视区域。如果不想,设置fixed: false即可

类型:Boolean,默认:true

默认情况下,你可以在弹层右下角拖动来拉伸尺寸。如果对指定的弹层屏蔽该功能,设置 false即可。该参数对loading、tips层无效

类型:Function,默认:null

当你拖拽弹层右下角对窗体进行尺寸调整时,如果你设定了该回调,则会执行。回调返回一个参数:当前层的DOM对象

</>code

resizing: function(layero){
console.log(layero);
}

类型:Boolean,默认:true

默认允许浏览器滚动,如果设定scrollbar: false,则屏蔽

类型:Number,默认:360

请注意:只有当area: 'auto'时,maxWidth的设定才有效。

类型:Number,默认:无

请注意:只有当高度自适应时,maxHeight的设定才有效。

类型:,默认:19891014(贤心生日 0.0)

一般用于解决和其它组件的层叠冲突。

类型:String/DOM/Boolean,默认:'.layui-layer-title'

默认是触发标题区域拖拽。如果你想单独定义,指向元素的选择器或者DOM即可。如move: '.mine-move'。你还配置设定move: false来禁止拖拽

类型:Boolean,默认:false

默认只能在窗口内拖拽,如果你想让拖到窗外,那么设定moveOut: true即可

类型:Function,默认:null

默认不会触发moveEnd,如果你需要,设定moveEnd: function(layero){}即可。其中layero为当前层的DOM对象

类型:Number/Array,默认:2

tips层的私有参数。支持四个方向,通过1-4进行方向设定。如tips: 3则表示在元素的下面出现。有时你还可能会定义一些颜色,可以设定tips: [1, '#c00']

类型:Boolean,默认:false

允许多个意味着不会销毁之前的tips层。通过tipsMore: true开启

类型:Function,默认:null

当你需要在层创建完毕时即执行一些语句,可以通过该回调。success会携带两个参数,分别是当前层DOM当前层索引。如:

 

</>code

layer.open({
content: '测试回调',
success: function(layero, index){
console.log(layero, index);
}
});

类型:Function,默认:null

该回调携带两个参数,分别为当前层索引、当前层DOM对象。如:

 

</>code

layer.open({
content: '测试回调',
yes: function(index, layero){
//do something
layer.close(index); //如果设定了yes回调,需进行手工关闭
}
});

类型:Function,默认:null

该回调携带两个参数,分别为:当前层索引参数(index)、当前层的DOM对象(layero),默认会自动触发关闭。如果不想关闭,return false即可,如;

 

</>code

cancel: function(index, layero){
if(confirm('确定要关闭么')){ //只有当点击confirm框的确定时,该层才会关闭
layer.close(index)
}
return false;
}

类型:Function,默认:null

无论是确认还是取消,只要层被销毁了,end都会执行,不携带任何参数。

类型:Function,默认:null

携带两个参数,即当前层 DOM、当前层索引

 

</>code

min: function(layero, index){ //index 参数为 layui 2.6.6 或独立版 layer 3.5.0 开始新增
//当层最小化时触发

//自定义操作,并阻止默认最小化
//layer.min(index); //单独执行最小化
//return false; //阻止默认最小化
}

类型:Boolean,默认:true

layui 2.6.6 或独立版 layer 3.5.0 开始新增

layer.config(options) - 初始化全局配置

layer.ready(callback) - 初始化就绪

layer.open(options) - 原始核心方法

layer.alert(content, options, yes) - 普通信息框

layer.confirm(content, options, yes, cancel) - 询问框

layer.msg(content, options, end) - 提示框

layer.load(icon, options) - 加载层

layer.tips(content, follow, options) - tips层

上面主要是一些弹层的调用方式,而下面介绍的是一些辅助性的方法

layer.close(index) - 关闭指定层

layer.closeAll(type) - 关闭所有层

layer.style(index, cssStyle) - 重新定义层的样式

layer.title(title, index) - 改变层的标题

layer.getChildFrame(selector, index) - 获取iframe页的DOM

layer.getFrameIndex(windowName) - 获取特定iframe层的索引

layer.iframeAuto(index) - 指定iframe层自适应

layer.iframeSrc(index, url) - //重置特定iframe url

layer.setTop(layero) -置顶当前窗口

layer.full()、layer.min()、layer.restore() - 手工执行最大小化

这是一个可以重要也可以不重要的方法,重要的是,它的权利真的很大,尤其是在模块化加载layer时,你会发现你必须要用到它。它不仅可以配置一些诸如路径、加载的模块,甚至还可以决定整个弹层的默认参数。而说它不重要,是因为多数情况下,你会发现,你似乎不是那么十分需要它。但你真的需要认识一下这位伙计。

如果您是采用seajs或者requirejs加载layer,你需要执行该方法来完成初始化的配置。比如:

 

</>code

layer.config({
path: '/res/layer/' //layer.js所在的目录,可以是绝对目录,也可以是相对目录
});
//这样的话,layer就会去加载一些它所需要的配件,比如 css 等。
//当然,你即便不用seajs或者requirejs,也可以通过上述方式设定路径

如果你是采用合并的方式引入 layer,那么您需要在 script 标签上加一个自定义属性 merge="true"。如:

 

</>code

<script src="?a.js&layer.js" merge="true">

如此,layer 则不会去自动获取路径,但你需要通过以下方式来完成初始化的配置
layer.config({
path: '/res/layer/' //layer.js 所在的目录,可以是绝对目录,也可以是相对目录
});

除上述之外,如果您采用的是独立的 layer,那么你还可以在动态加载 layer 之前预先定义一个我们约定好的全局对象:

 

</>code

<script>
var LAYUI_GLOBAL = {
layer_dir: '/res/layer/' //layer 所在目录(layer 3.5 开始新增)
};
</script>
提示 1:上述只针对独立版 layer,其 LAYUI_GLOBAL 设定的 layer_dir 优先级高于 layer.config 设定的 path;
提示 2:如果是 layui 加载的 layer,可以无视上述所有的目录设定。前置工作都会在 layui 内部完成。

另外,layer.config 还可以配置层 默认的基础参数,如:

 

</>code

layer.config({
anim: 1, //默认动画风格
skin: 'layui-layer-molv' //默认皮肤
//…
});
//除此之外,extend 还允许你加载拓展的 css 皮肤,如:
layer.config({
//如果是独立版的layer,则将 myskin 存放在 ./skin 目录下
//如果是layui中使用layer,则将 myskin 存放在 ./css/modules/layer 目录下
extend: 'myskin/style.css'
});
  1. //具体的皮肤定制,可以参见:skin参数说明

由于我们的layer内置了轻量级加载器,所以你根本不需要单独引入css等文件。但是加载总是需要过程的。当你在页面一打开就要执行弹层时,你最好是将弹层放入ready方法中,如:

 

</>code

//页面一打开就执行弹层
layer.ready(function(){
layer.msg('很高兴一开场就见到你');
});

我是华丽的酱油:介绍完上面两位引导者,接下来我们真正的主角闪亮登场了。此处应有掌声 ^,^

基本上是露脸率最高的方法,不管是使用哪种方式创建层,都是走layer.open(),创建任何类型的弹层都会返回一个当前层索引,上述的options即是基础参数,另外,该文档统一采用options作为基础参数的标识例子:

 

</>code

var index = layer.open({
content: 'test'
});
  1. //拿到的index是一个重要的凭据,它是诸如layer.close(index)等方法的必传参数。

噢,请等等,上面这位主角的介绍篇幅怎么看怎么都觉得跟它的地位不符,作者在文档中只给了它如此可怜的一块地??这是因为,它真的已经大众得不能再大众了,你真正需要了解的,是它的内部器官,即上面一大篇幅介绍的各种基础参数。 ←_←

它的弹出似乎显得有些高调,一般用于对用户造成比较强烈的关注,类似系统alert,但却比alert更灵便。它的参数是自动向左补齐的。通过第二个参数,可以设定各种你所需要的基础参数,但如果你不需要的话,直接写回调即可。如

 

</>code

//eg1
layer.alert('只想简单的提示');
//eg2
layer.alert('加了个图标', {icon: 1}); //这时如果你也还想执行yes回调,可以放在第三个参数中。
//eg3
layer.alert('有了回调', function(index){
//do something

layer.close(index);
});

类似系统confirm,但却远胜confirm,另外它不是和系统的confirm一样阻塞你需要把交互的语句放在回调体中。同样的,它的参数也是自动补齐的。

 

</>code

//eg1
layer.confirm('is not?', {icon: 3, title:'提示'}, function(index){
//do something

layer.close(index);
});
//eg2
layer.confirm('is not?', function(index){
//do something

layer.close(index);
});

我们在源码中用了相对较大的篇幅来定制了这个msg,目的是想将其打造成露脸率最高的提示框。而事实上我的确也在大量地使用它。因为它简单,而且足够得自觉,它不仅占据很少的面积,而且默认还会3秒后自动消失所有这一切都决定了我对msg的爱。因此我赋予了它许多可能在外形方面,它坚持简陋的变化,在作用方面,它坚持零用户操作。而且它的参数也是自动补齐的。

 

</>code

//eg1
layer.msg('只想弱弱提示');
//eg2
layer.msg('有表情地提示', {icon: 6});
//eg3
layer.msg('关闭后想做些什么', function(){
//do something
});
//eg
layer.msg('同上', {
icon: 1,
time: 2000 //2秒关闭(如果不配置,默认是3秒)
}, function(){
//do something
});

type:3的深度定制。load并不需要你传太多的参数,但如果你不喜欢默认的加载风格,你还有选择空间。icon支持传入0-2如果是0,无需传。另外特别注意一点:load默认是不会自动关闭的,因为你一般会在ajax回调体中关闭它。

 

</>code

//eg1
var index = layer.load();
//eg2
var index = layer.load(1); //换了种风格
//eg3
var index = layer.load(2, {time: 10*1000}); //又换了种风格,并且设定最长等待10秒
//关闭
layer.close(index);

type:4的深度定制。也是我本人比较喜欢的一个层类型,因为它拥有和msg一样的低调和自觉,而且会智能定位,即灵活地判断它应该出现在哪边。默认是在元素右边弹出

 

</>code

//eg1
layer.tips('只想提示地精准些', '#id');
//eg 2
$('#id').on('click', function(){
var that = this;
layer.tips('只想提示地精准些', that); //在元素的事件回调体中,follow直接赋予this即可
});
//eg 3
layer.tips('在上面', '#id', {
tips: 1
});

关于它似乎没有太多介绍的必要,唯一让你疑惑的,可能就是这个index了吧。事实上它非常容易得到。

 

</>code

//当你想关闭当前页的某个层时
var index = layer.open();
var index = layer.alert();
var index = layer.load();
var index = layer.tips();
//正如你看到的,每一种弹层调用方式,都会返回一个index
layer.close(index); //此时你只需要把获得的index,轻轻地赋予layer.close即可

//如果你想关闭最新弹出的层,直接获取layer.index即可
layer.close(layer.index); //它获取的始终是最新弹出的某个层,值是由layer内部动态递增计算的

//当你在iframe页面关闭自身时
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭

//关闭后的回调(layui 2.6.5、layer 3.4.0 新增)
layer.close(index, function(){
//do something
});

如果你很懒,你不想去获取index你只想关闭。那么closeAll真的可以帮上你。如果你不指向层类型的话,它会销毁掉当前页所有的layer层。当然,如果你只想关闭某个类型的层,那么你可以

 

</>code

layer.closeAll(); //疯狂模式,关闭所有层
layer.closeAll('dialog'); //关闭信息框
layer.closeAll('page'); //关闭所有页面层
layer.closeAll('iframe'); //关闭所有的iframe层
layer.closeAll('loading'); //关闭加载层
layer.closeAll('tips'); //关闭所有的tips层

//关闭后的回调(layui 2.6.5、layer 3.4.0 新增)
layer.closeAll('loading', function(){ //关闭 loading 并执行回调
//do something
});
layer.closeAll(function(){ //关闭所有层并执行回调
//do something
});

该方法对loading层和tips层无效。参数index为层的索引,cssStyle允许你传入任意的css属性

 

</>code

//重新给指定层设定width、top等
layer.style(index, {
width: '1000px',
top: '10px'
});

使用方式:layer.title('标题变了', index)

当你试图在当前页获取iframe页的DOM元素时,你可以用此方法。selector即iframe页的选择器

 

</>code

layer.open({
type: 2,
content: 'test/iframe.html',
success: function(layero, index){
var body = layer.getChildFrame('body', index);
var iframeWin = window[layero.find('iframe')[0]['name']]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.method();
console.log(body.html()) //得到iframe页的body内容
body.find('input').val('Hi,我是从父页来的')
}
});

此方法一般用于在iframe页关闭自身时用到。

 

</>code

//假设这是iframe页
var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
parent.layer.close(index); //再执行关闭

调用该方法时,iframe层的高度会重新进行适应

似乎不怎么常用的样子。使用方式:layer.iframeSrc(index, 'http://sentsin.com')

非常强大的一个方法,虽然一般很少用。但是当你的页面有很多很多layer窗口,你需要像Window窗体那样,点击某个窗口,该窗体就置顶在上面,那么setTop可以来轻松实现。它采用巧妙的逻辑,以使这种置顶的性能达到最优

 

</>code

//通过这种方式弹出的层,每当它被选择,就会置顶。
layer.open({
type: 2,
shade: false,
area: '500px',
maxmin: true,
content: 'http:/',
zIndex: layer.zIndex, //重点1
success: function(layero){
layer.setTop(layero); //重点2
}
});

一般用于在自定义元素上触发最大化、最小化和全屏。

 

</>code

layer.full(index); //执行最大化
layer.min(index); //执行最小化
layer.restore(index); //执行还原

layer.prompt(options, yes) - 输入层

layer.tab(options) - tab层

layer.photos(options) - 相册层

prompt的参数也是向前补齐的。options不仅可支持传入基础参数,还可以传入prompt专用的属性。当然,也可以不传。yes携带value 表单值index 索引elem 表单元素

 

</>code

//prompt层新定制的成员如下
{
formType: 1, //输入框类型,支持0(文本)默认1(密码)2(多行文本)
value: '', //初始时的值,默认空字符
maxlength: 140, //可输入文本的最大长度,默认500
}

//例子1
layer.prompt(function(value, index, elem){
alert(value); //得到value
layer.close(index);
});

//例子2
layer.prompt({
formType: 2,
value: '初始值',
title: '请输入值',
area: ['800px', '350px'] //自定义文本域宽高
}, function(value, index, elem){
alert(value); //得到value
layer.close(index);
});

tab层只单独定制了一个成员,即tab: [],这个好像没有什么可介绍的,简单粗暴看例子

 

</>code

layer.tab({
area: ['600px', '300px'],
tab: [{
title: 'TAB1',
content: '内容1'
}, {
title: 'TAB2',
content: '内容2'
}, {
title: 'TAB3',
content: '内容3'
}]
});

相册层,也可以称之为图片查看器。它的出场动画从layer内置的动画类型中随机展现。photos支持传入json和直接读取页面图片两种方式。如果是json传入,如下:

 

</>code

$.getJSON('/jquery/layer/test/photos.json', function(json){
layer.photos({
photos: json
,anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
});
});
//而返回的json需严格按照如下格式:

</>code
{
"title": "", //相册标题
"id": 123, //相册id
"start": 0, //初始显示的图片序号,默认0
"data": [ //相册包含的图片,数组格式
{
"alt": "图片名",
"pid": 666, //图片id
"src": "", //原图地址
"thumb": "" //缩略图地址
}
]
}

如果是直接从页面中获取图片,那么需要指向图片的父容器,并且你的img可以设定一些规定的属性(但不是必须的)。

 

</>code

//HTML示例
<div id="layer-photos-demo" class="layer-photos-demo">
<img layer-pid="图片id,可以不写" layer-src="大图地址" src="缩略图" alt="图片名">
<img layer-pid="图片id,可以不写" layer-src="大图地址" src="缩略图" alt="图片名">
</div>

<script>
//调用示例
layer.photos({
photos: '#layer-photos-demo'
,anim: 5 //0-6的选择,指定弹出图片动画类型,默认随机(请注意,3.0之前的版本用shift参数)
});
</script>

看看一个实例呗:

  

第二种方式的图片查看器显然更加简单,因为无需像第一种那样返回规定的json,但是他们还是有各自的应用场景的,你可以按照你的需求进行选择。另外,photos还有个tab回调,切换图片时触发。

 

</>code

layer.photos({
photos: json/选择器,
tab: function(pic, layero){
console.log(pic) //当前图片的一些信息
}
});

二、日期和时间组件文档 - layui.laydate

如你所见,layDate 在 layui 2.0 的版本中迎来一次重生。无论曾经它给你带来过多么糟糕的体验,从今往后,所有的旧坑都将弥合。全面重写的 layDate 包含了大量的更新,其中主要以: 年选择器年月选择器日期选择器时间选择器日期时间选择器 五种类型的选择方式为基本核心,并且均支持范围选择(即双控件)。内置强劲的自定义日期格式解析和合法校正机制,含中文版和国际版,主题简约却又不失灵活多样。由于内部采用的是零依赖的原生 JavaScript 编写,因此又可作为独立组件使用。毫无疑问,这是 layui 的虔心之作。
模块加载名称: laydate,独立版本: http://laydate/

快速使用

和 layer 一样,你可以在 layui 中使用 layDate,也可直接使用 layDate 独立版,请按照你的实际需求来选择。

场景用前准备调用方式
1. 在 layui 模块中使用下载 layui 后,引入layui.csslayui.js即可通过layui.use('laydate', callback)加载模块后,再调用方法
2. 作为独立组件使用去 layDate 独立版本官网下载组件包,引入 laydate.js 即可直接调用方法使用

这是一个最简单的示例:

对应的代码如下:

 

在 layui 模块中使用code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layDate快速使用</title>
<link rel="stylesheet" href="/static/build/layui.css" media="all">
</head>
<body>

<div class="layui-inline"> <!-- 注意:这一层元素并不是必须的 -->
<input type="text" class="layui-input" id="test1">
</div>

<script src="/static/build/layui.js"></script>
<script>
layui.use('laydate', function(){
var laydate = layui.laydate;

//执行一个laydate实例
laydate.render({
elem: '#test1' //指定元素
});
});
</script>
</body>
</html>
 

作为独立组件使用code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>使用 layDate 独立版</title>
</head>
<body>

<input type="text" id="test1">

<script src="laydate.js"></script>
<script>
//执行一个laydate实例
laydate.render({
elem: '#test1' //指定元素
});
</script>
</body>
</html>

除了在组件加载方式有一些小小的不同,其它都完全类似

基础参数选项

通过核心方法:laydate.render(options) 来设置基础参数,也可以通过方法:laydate.set(options) 来设定全局基础参数.

elem - 绑定元素

类型:String/DOM,默认值:

必填项,用于绑定执行日期渲染的元素,值一般为选择器,或DOM对象

 

</>code

laydate.render({
elem: '#test' //或 elem: document.getElementById('test')、elem: lay('#test') 等
});

type - 控件选择类型

类型:String,默认值:date

用于单独提供不同的选择器类型,可选值如下表:

type可选值名称用途
year年选择器只提供年列表选择
month年月选择器只提供年、月选择
date日期选择器可选择:年、月、日。type默认值,一般可不填
time时间选择器只提供时、分、秒选择
datetime日期时间选择器可选择:年、月、日、时、分、秒
 

</>code

//年选择器
laydate.render({
elem: '#test'
,type: 'year'
});

//年月选择器
laydate.render({
elem: '#test'
,type: 'month'
});

//日期选择器
laydate.render({
elem: '#test'
//,type: 'date' //默认,可不填
});

//时间选择器
laydate.render({
elem: '#test'
,type: 'time'
});

//日期时间选择器
laydate.render({
elem: '#test'
,type: 'datetime'
});

range - 开启左右面板范围选择

类型:Boolean/String/Array,默认值:false

如果设置 true,将默认采用 “ - ” 分割。 你也可以直接设置 分割字符。五种选择器类型均支持左右面板的范围选择。

 

</>code

//日期范围选择
laydate.render({
elem: '#test'
,range: true //或 range: '~' 来自定义分割字符
});

//日期时间范围选择
laydate.render({
elem: '#test'
,type: 'datetime'
,range: true
});

//时间范围选择
laydate.render({
elem: '#test'
,type: 'time'
,range: true
});

//年范围选择
laydate.render({
elem: '#test'
,type: 'year'
,range: true
});

//年月范围选择
laydate.render({
elem: '#test'
,type: 'month'
,range: true
});

如果您要将开始时间和结束时间分开,那么还可以将 range 参数设置为数组,如:

 

</>code

<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">日期范围</label>
<div class="layui-inline" id="test-range">
<div class="layui-input-inline">
<input type="text" id="startDate" class="layui-input" placeholder="开始日期">
</div>
<div class="layui-form-mid">-</div>
<div class="layui-input-inline">
<input type="text" id="endDate" class="layui-input" placeholder="结束日期">
</div>
</div>
</div>
</div>
<script>
laydate.render({
elem: '#test-range' //开始时间和结束时间所在 input 框的父选择器
//设置开始日期、日期日期的 input 选择器
,range: ['#startDate', '#endDate'] //数组格式为 layui 2.6.6 开始新增
});
</script>

format - 自定义格式

类型:String,默认值:yyyy-MM-dd

通过日期时间各自的格式符和长度,来设定一个你所需要的日期格式。layDate 支持的格式如下:

格式符说明
yyyy年份,至少四位数。如果不足四位,则前面补零
y年份,不限制位数,即不管年份多少位,前面均不补零
MM月份,至少两位数。如果不足两位,则前面补零。
M月份,允许一位数。
dd日期,至少两位数。如果不足两位,则前面补零。
d日期,允许一位数。
HH小时,至少两位数。如果不足两位,则前面补零。
H小时,允许一位数。
mm分钟,至少两位数。如果不足两位,则前面补零。
m分钟,允许一位数。
ss秒数,至少两位数。如果不足两位,则前面补零。
s秒数,允许一位数。

通过上述不同的格式符组合成一段日期时间字符串,可任意排版,如下所示:

格式示例值
yyyy-MM-dd HH:mm:ss2017-08-18 20:08:08
yyyy年MM月dd日 HH时mm分ss秒2017年08月18日 20时08分08秒
yyyyMMdd20170818
dd/MM/yyyy18/08/2017
yyyy年M月2017年8月
M月d日8月18日
北京时间:HH点mm分北京时间:20点08分
yyyy年的M月某天晚上,大概H点2017年的8月某天晚上,大概20点
 

</>code

//自定义日期格式
laydate.render({
elem: '#test'
,format: 'yyyy年MM月dd日' //可任意组合
});

value - 初始值

类型:String,默认值:new Date()

支持传入符合format参数设定的日期格式字符,或者 new Date()

 

</>code

//传入符合format格式的字符给初始值
laydate.render({
elem: '#test'
,value: '2018-08-18' //必须遵循format参数设定的格式
});

//传入Date对象给初始值
laydate.render({
elem: '#test'
,value: new Date(1534766888000) //参数即为:2018-08-20 20:08:08 的时间戳
});

isInitValue - 初始值填充

类型:Boolean,默认值:true

用于控制是否自动向元素填充初始值(需配合 value 参数使用)

 

</>code

laydate.render({
elem: '#test'
,value: '2017-09-10'
,isInitValue: false //是否允许填充初始值,默认为 true
});
注意:该参数为 layui 2.3.0 新增。

isPreview - 是否开启选择值预览

类型:Boolean,默认值:true

用于控制是否显示当前结果的预览(type 为 datetime 时不开启)

 

</>code

laydate.render({
elem: '#test'
,isPreview: false //禁用面板左下角选择值的预览,默认 true
});
注意:该参数为 layui 2.6.6 新增。

min/max - 最小/大范围内的日期时间值

类型:string,默认值:min: '1900-1-1'max: '2099-12-31'

设定有限范围内的日期或时间值,不在范围内的将不可选中。这两个参数的赋值非常灵活,主要有以下几种情况:

1.如果值为字符类型,则:年月日必须用 -(中划线)分割时分秒必须用 :(半角冒号)号分割。这里并非遵循 format 设定的格式
2.如果值为整数类型,且数字<86400000,则数字代表天数,如:min: -7,即代表最小日期在7天前,正数代表若干天后
3.如果值为整数类型,且数字 ≥ 86400000,则数字代表时间戳,如:max: 4073558400000,即代表最大日期在:公元3000年1月1日
 

示例code

//日期有效范围只限定在:2017年
laydate.render({
elem: '#test'
,min: '2017-1-1'
,max: '2017-12-31'
});

//日期有效范围限定在:过去一周到未来一周
laydate.render({
elem: '#test'
,min: -7 //7天前
,max: 7 //7天后
});

//日期时间有效范围的设定:
laydate.render({
elem: '#test'
,type: 'datetime'
,min: '2017-8-11 12:30:00'
,max: '2017-8-18 12:30:00'
});

//时间有效范围设定在: 上午九点半到下午五点半
laydate.render({
elem: '#test'
,type: 'time'
,min: '09:30:00'
,max: '17:30:00'
});

毫不保留地说,min和max参数是两个非常强大的存在,合理运用,可帮助用户在日期与时间的选择上带来更为友好的约束与体验。

trigger - 自定义弹出控件的事件

类型:String,默认值:focus,如果绑定的元素非输入框,则默认事件为:click

 

</>code

//自定义事件
laydate.render({
elem: '#test'
,trigger: 'click' //采用click弹出
});

show - 默认显示

类型:Boolean,默认值:false

如果设置: true,则控件默认显示在绑定元素的区域。通常用于外部事件调用控件,如:

 

</>code

//默认显示
laydate.render({
elem: '#test'
,show: true //直接显示
});

//外部事件调用
lay('#test1').on('click', function(e){ //假设 test1 是一个按钮
laydate.render({
elem: '#test'
,show: true //直接显示
,closeStop: '#test1' //这里代表的意思是:点击 test1 所在元素阻止关闭事件冒泡。如果不设定,则无法弹出控件
});
});

position - 定位方式

类型:String,默认值:absolute

用于设定控件的定位方式,有以下三种可选值:

position 可选值说明
abolute绝对定位,始终吸附在绑定元素周围。默认值
fixed固定定位,初始吸附在绑定元素周围,不随浏览器滚动条所左右。一般用于在固定定位的弹层中使用。
static静态定位,控件将直接嵌套在指定容器中。
注意:请勿与 show 参数的概念搞混淆。show为 true 时,控件仍然是采用绝对或固定定位。而这里是直接嵌套显示

下面是一个直接嵌套显示的例子:

2022 年7 月

262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

2022-07-12

重置现在确定

 

</>code

【HTML】

<span id="testView"></span>

<div id="test2"></div>

【JS】:

//嵌套在指定容器中

laydate.render({

elem: '#test2'

,position: 'static'

,change: function(value, date){ //监听日期被切换

lay('#testView').html(value);

}

});

zIndex - 层叠顺序

类型:Number,默认值:66666666

一般用于解决与其它元素的互相被遮掩的问题。如果 position 参数设为 static 时,该参数无效。

 

</>code

//设定控件的层叠顺序
laydate.render({
elem: '#test'
,zIndex: 99999999
});

showBottom - 是否显示底部栏

类型:Boolean,默认值:true

如果设置 false,将不会显示控件的底部栏区域

 

</>code

//不显示底部栏
laydate.render({
elem: '#test'
,showBottom: false
});

btns - 工具按钮

类型:Array,默认值:['clear', 'now', 'confirm']

右下角显示的按钮,会按照数组顺序排列,内置可识别的值有:clear、now、confirm

 

</>code

//只显示清空和确认
laydate.render({
elem: '#test'
,btns: ['clear', 'confirm']
});

lang - 语言

类型:String,默认值:cn

我们内置了两种语言版本:cn(中文版)、en(国际版,即英文版)。这里并没有开放自定义文字,是为了避免繁琐的配置。

 

</>code

//国际版
laydate.render({
elem: '#test'
,lang: 'en'
});

theme - 主题

类型:String,默认值:default

我们内置了多种主题,theme的可选值有:default(默认简约)、molv(墨绿背景)、#颜色值(自定义颜色背景)、grid(格子主题)

 

</>code

//墨绿背景主题
laydate.render({
elem: '#test'
,theme: 'molv'
});

//自定义背景色主题 - 非常实用
laydate.render({
elem: '#test'
,theme: '#393D49'
});

//格子主题
laydate.render({
elem: '#test'
,theme: 'grid'
});

另外,你还可以传入其它字符,如:theme: 'xxx',那么控件将会多出一个 class="laydate-theme-xxx" 的CSS类,以便于你单独定制主题。

calendar - 是否显示公历节日

类型:Boolean,默认值:false

我们内置了一些我国通用的公历重要节日,通过设置 true 来开启。国际版不会显示。

 

</>code

//允许显示公历节日
laydate.render({
elem: '#test'
,calendar: true
});

mark - 标注重要日子

类型:Object,默认值:

calendar 参数所代表的公历节日更多情况下是一个摆设。因此,我们还需要自定义标注重要日子,比如结婚纪念日?日程等?它分为以下两种:

标注格式说明
每年的日期{'0-9-18': '国耻'}0 即代表每一年
每月的日期{'0-0-15': '中旬'}0-0 即代表每年每月(layui 2.1.1/layDate 5.0.4 新增)
特定的日期{'2017-8-21': '发布')-

可同时设定多个,如:

 

</>code

//标注重要日子
var ins1 = laydate.render({
elem: '#test'
,mark: {
'0-10-14': '生日'
,'0-12-31': '跨年' //每年12月31日
,'0-0-10': '工资' //每个月10号
,'2017-8-15': '' //具体日期
,'2017-8-20': '预发' //如果为空字符,则默认显示数字+徽章
,'2017-8-21': '发布'
}
,done: function(value, date){
if(date.year === 2017 && date.month === 8 && date.date === 15){ //点击2017年8月15日,弹出提示语
ins1.hint('中国人民抗日战争胜利72周年');
}
}
});

非常实用的存在,是时候利用它制作你的日程表了。

控件初始打开的回调

控件在打开时触发,回调返回一个参数:初始的日期时间对象

 

</>code

laydate.render({
elem: '#test'
,ready: function(date){
console.log(date); //得到初始的日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
}
});

日期时间被切换后的回调

年月日时间被切换时都会触发。回调返回三个参数,分别代表:生成的值日期时间对象结束的日期时间对象

 

</>code

laydate.render({
elem: '#test'
,change: function(value, date, endDate){
console.log(value); //得到日期生成的值,如:2017-08-18
console.log(date); //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
console.log(endDate); //得结束的日期时间对象,开启范围选择(range: true)才会返回。对象成员同上。
}
});

控件选择完毕后的回调

点击日期、清空、现在、确定均会触发。回调返回三个参数,分别代表:生成的值日期时间对象结束的日期时间对象

 

</>code

laydate.render({
elem: '#test'
,done: function(value, date, endDate){
console.log(value); //得到日期生成的值,如:2017-08-18
console.log(date); //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
console.log(endDate); //得结束的日期时间对象,开启范围选择(range: true)才会返回。对象成员同上。
}
});

弹出控件提示

事实上,执行核心方法 laydate.render(options) 会返回一个当前实例对象。其中包含一些成员属性和方法,比如:hint方法

 

</>code

var ins1 = laydate.render({
elem: '#test'
,change: function(value, date, endDate){
ins1.hint(value); //在控件上弹出value值
}
});

配置基础路径

如果你不是采用 layui 或者普通 script 标签方式加载的 laydate.js,而是采用 requirejs 等其它方式引用 laydate,那么你需要设置基础路径,以便 laydate.css 完成加载。

 

</>code

laydate.path = '/static/xxx/'; //laydate.js 所在目录

//配置好路径后,再调用
laydate.render(options);

除上述之外,如果您采用的是独立的 laydate,那么你还可以在动态加载 laydate之前预先定义一个我们约定好的全局对象:

 

</>code

<script>
var LAYUI_GLOBAL = {
laydate_dir: '/res/laydate/' //laydate 所在目录(laydate 5.3.0 开始新增)
};
</script>
提示 1:上述只针对独立版 laydate,其 LAYUI_GLOBAL 设定的 laydate_dir 优先级高于 laydate.path;
提示 2:如果是 layui 加载的 laydate,可以无视上述所有的目录设定。前置工作都会在 layui 内部完成。

其它方法

方法名备注
laydate.getEndDate(month, year)获取指定年月的最后一天,month默认为当前月,year默认为当前年。如:
var endDate1 = laydate.getEndDate(10); //得到31
var endDate2 = laydate.getEndDate(2, 2080); //得到29

三、分页模块文档 - layui.laypage

layPage 致力于提供极致的分页逻辑,既可轻松胜任异步分页,也可作为页面刷新式分页。自 layui 2.0 开始,无论是从核心代码还是API设计,layPage 都完成了一次蜕变。清爽的 UI、灵活的排版,极简的调用方式,这一切的优质元素,都将毫无违和感地镶嵌在你的页面之中。
模块加载名称: laypage

快速使用

laypage 的使用非常简单,指向一个用于存放分页的容器,通过服务端得到一些初始值,即可完成分页渲染:

 

在 layui 模块中使用code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layPage快速使用</title>
<link rel="stylesheet" href="/static/build/layui.css" media="all">
</head>
<body>

<div id="test1"></div>

<script src="/static/build/layui.js"></script>
<script>
layui.use('laypage', function(){
var laypage = layui.laypage;

//执行一个laypage实例
laypage.render({
elem: 'test1' //注意,这里的 test1 是 ID,不用加 # 号
,count: 50 //数据总数,从服务端得到
});
});
</script>
</body>
</html>

基础参数选项

通过核心方法:laypage.render(options) 来设置基础参数。由于使用非常简单,本篇直接罗列核心接口的参数选项

参数选项说明类型默认值
elem指向存放分页的容器,值可以是容器ID、DOM对象。如:
1. elem: 'id' 注意:这里不能加 # 号
2. elem: document.getElementById('id')
String/Object-
count数据总数。一般通过服务端得到Number-
limit每页显示的条数。laypage将会借助 count 和 limit 计算出分页数。Number10
limits每页条数的选择项。如果 layout 参数开启了 limit,则会出现每页条数的select选择框Array[10, 20, 30, 40, 50]
curr起始页。一般用于刷新类型的跳页以及HASH跳页。如:
 

</>code

  1. //开启location.hash的记录
  2. laypage.render({
  3. elem: 'test1'
  4. ,count: 500
  5. ,curr: location.hash.replace('#!fenye=', '') //获取起始页
  6. ,hash: 'fenye' //自定义hash值
  7. });
Number1
groups连续出现的页码个数Number5
prev自定义“上一页”的内容,支持传入普通文本和HTMLString上一页
next自定义“下一页”的内容,同上String下一页
first自定义“首页”的内容,同上String1
last自定义“尾页”的内容,同上String总页数值
layout自定义排版。可选值有:count(总条目输区域)、prev(上一页区域)、page(分页区域)、next(下一页区域)、limit(条目选项区域)、refresh(页面刷新区域。注意:layui 2.3.0 新增) 、skip(快捷跳页区域)Array['prev', 'page', 'next']
theme自定义主题。支持传入:颜色值,或任意普通字符。如:
1. theme: '#c00'
2. theme: 'xxx' //将会生成 class="layui-laypage-xxx" 的CSS类,以便自定义主题
String-
hash开启location.hash,并自定义 hash 值。如果开启,在触发分页时,会自动对url追加:#!hash值={curr} 利用这个,可以在页面载入时就定位到指定页String/Booleanfalse

jump - 切换分页的回调

当分页被切换时触发,函数返回两个参数:obj(当前分页的所有选项值)、first(是否首次,一般用于初始加载的判断)

 

</>code

laypage.render({
elem: 'test1'
,count: 70 //数据总数,从服务端得到
,jump: function(obj, first){
//obj包含了当前分页的所有参数,比如:
console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
console.log(obj.limit); //得到每页显示的条数

//首次不执行
if(!first){
//do something
}
}
});

四、模板引擎文档 - layui.laytpl

laytpl 是 JavScript 模板引擎,在字符解析上有着比较出色的表现,欠缺之处在于异常调试上。由于传统意义的前端模板引擎已经变得不再流行,所以 laytpl 后续可能会进行重写,目前方向暂时还没有想好,预计会在layui比较稳定后开始实施。

模块加载名称:laytpl,在线调试:http://demo/laytpl.html

快速使用

laytpl 模板可与数据共存,这意味着可直接在模板中处理逻辑。

 

</>code

layui.use('laytpl', function(){
var laytpl = layui.laytpl;

//直接解析字符
laytpl('{{ d.name }}是一位公猿').render({
name: '贤心'
}, function(string){
console.log(string); //贤心是一位公猿
});

//你也可以采用下述同步写法,将 render 方法的回调函数剔除,可直接返回渲染好的字符
var string = laytpl('{{ d.name }}是一位公猿').render({
name: '贤心'
});
console.log(string); //贤心是一位公猿

//如果模板较大,你也可以采用数据的写法,这样会比较直观一些
laytpl([
'{{ d.name }}是一位公猿'
,'其它字符 {{ d.content }} 其它字符'
].join(''))
});

你也可以将模板存储在页面或其它任意位置:

 

</>code

//第一步:编写模版。你可以使用一个script标签存放模板,如:
<script id="demo" type="text/html">
<h3>{{ d.title }}</h3>
<ul>
{{# layui.each(d.list, function(index, item){ }}
<li>
<span>{{ item.modname }}</span>
<span>{{ item.alias }}:</span>
<span>{{ item.site || '' }}</span>
</li>
{{# }); }}
{{# if(d.list.length === 0){ }}
无数据
{{# } }}
</ul>
</script>

//第二步:建立视图。用于呈现渲染结果。
<div id="view"></div>

//第三步:渲染模版
var data = { //数据
"title":"Layui常用模块"
,"list":[{"modname":"弹层","alias":"layer","site":"layer.layui.com"},{"modname":"表单","alias":"form"}]
}
var getTpl = demo.innerHTML
,view = document.getElementById('view');
laytpl(getTpl).render(data, function(html){
view.innerHTML = html;
});

模版语法

语法说明示例
{{ d.field }}输出一个普通字段,不转义html
 

</>code

  1. <div>{{ d.content }}</div>
{{= d.field }}输出一个普通字段,并转义html
 

</>code

  1. <h2>{{= d.title }}</h2>
{{# JavaScript表达式 }}JS 语句。一般用于逻辑处理。用分隔符加 # 号开头。

注意:如果你是想输出一个函数,正确的写法是:{{ fn() }},而不是:{{# fn() }}
 

</>code

  1. {{#
  2. var fn = function(){
  3. return '2017-08-18';
  4. };
  5. }}
  6. {{# if(true){ }}
  7. 开始日期:{{ fn() }}
  8. {{# } else { }}
  9. 已截止
  10. {{# } }}
{{! template !}}对一段指定的模板区域进行过滤,即不解析该区域的模板。注:layui 2.1.6 新增
 

</>code

  1. <div> {{! 这里面的模板不会被解析 !}}</div>

分隔符

如果模版默认的 {{ }} 分隔符与你的其它模板(一般是服务端模板)存在冲突,你也可以重新定义分隔符:

 

</>code

laytpl.config({
open: '<%',
close: '%>'
});

//分割符将必须采用上述定义的
laytpl([
'<%# var type = "公"; %>' //JS 表达式
,'<% d.name %>是一位<% type %>猿。'
].join('')).render({
name: '贤心'
}, function(string){
console.log(string); //贤心是一位公猿
});

五、table 数据表格文档 - layui.table

table 模块是我们的又一走心之作,在 layui 2.0 的版本中全新推出,是 layui 最核心的组成之一。它用于对表格进行一些列功能和动态化数据操作,涵盖了日常业务所涉及的几乎全部需求。支持固定表头、固定行、固定列左/列右,支持拖拽改变列宽度,支持排序,支持多级表头,支持单元格的自定义模板,支持对表格重载(比如搜索、条件筛选等),支持复选框,支持分页,支持单元格编辑等等一些列功能。尽管如此,我们仍将对其进行完善,在控制代码量和性能的前提下,不定期增加更多人性化功能。table 模块也将是 layui 重点维护的项目之一。

模块加载名称:table

快速使用

创建一个table实例最简单的方式是,在页面放置一个元素 <table id="demo"></table>,然后通过 table.render() 方法指定该容器,如下所示:

10000

user-0

城市-0

签名-0

255

57

作家

82830700

10001

user-1

城市-1

签名-1

884

27

词人

64928690

10002

user-2

城市-2

签名-2

650

31

酱油

6298078

10003

user-3

城市-3

签名-3

362

68

诗人

37117017

10004

user-4

城市-4

签名-4

807

6

作家

76263262

10005

user-5

城市-5

签名-5

173

87

作家

60344147

10006

user-6

城市-6

签名-6

982

34

作家

57768166

10007

user-7

城市-7

签名-7

727

28

作家

82030578

10008

user-8

城市-8

签名-8

951

14

词人

16503371

10009

user-9

城市-9

签名-9

484

75

词人

86801934

10010

user-10

城市-10

签名-10

1016

34

诗人

71294671

10011

user-11

城市-11

签名-11

492

6

诗人

8062783

10012

user-12

城市-12

签名-12

106

54

词人

42622704

10013

user-13

城市-13

签名-13

1047

63

诗人

59508583

10014

user-14

城市-14

签名-14

873

8

词人

72549912

10015

user-15

城市-15

签名-15

1068

28

作家

52737025

10016

user-16

城市-16

签名-16

862

86

酱油

37069775

10017

user-17

城市-17

签名-17

1060

69

作家

66099525

10018

user-18

城市-18

签名-18

866

74

词人

81722326

10019

user-19

城市-19

签名-19

682

51

词人

68647362

10020

user-20

城市-20

签名-20

770

87

诗人

92420248

10021

user-21

城市-21

签名-21

184

99

词人

71566045

10022

user-22

城市-22

签名-22

739

18

作家

60907929

10023

user-23

城市-23

签名-23

127

30

作家

14765943

10024

user-24

城市-24

签名-24

212

76

词人

59011052

10025

user-25

城市-25

签名-25

938

69

作家

91183097

10026

user-26

城市-26

签名-26

978

65

作家

48008413

10027

user-27

城市-27

签名-27

371

60

诗人

64419691

10028

user-28

城市-28

签名-28

977

37

作家

75935022

10029

user-29

城市-29

签名-29

647

27

酱油

97450636

123…100到第页确定共 1000 条10 条/页20 条/页30 条/页40 条/页50 条/页60 条/页70 条/页80 条/页90 条/页

上面你已经看到了一个简单数据表格的基本样子,你一定迫不及待地想知道它的使用方式。下面就是它对应的代码:

 

对应的代码code

<!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: '../../demo/table/user/-page=1&limit=30.js' //数据接口
,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: '职业', width: 80}
,{field: 'wealth', title: '财富', width: 135, sort: true}
]]
});

});
</script>
</body>
</html>

一切都并不会陌生:绑定容器、设置数据接口、在表头设定对应的字段,剩下的…就交给 layui 吧。你的牛刀是否早已饥渴难耐?那么不妨现在就去小试一波吧。数据接口可参考:返回的数据,规则在下文也有讲解。

三种初始化渲染方式

在上述“快速使用”的介绍中,你已经初步见证了 table 模块的信手拈来,但其使用方式并不止那一种。我们为了满足各种情况下的需求,对 table 模块做了三种初始化的支持,你可按照个人喜好和实际情况灵活使用。

方式机制适用场景
01.方法渲染用JS方法的配置完成渲染(推荐)无需写过多的 HTML,在 JS 中指定原始元素,再设定各项参数即可。
02.自动渲染HTML配置,自动渲染无需写过多 JS,可专注于 HTML 表头部分
03.转换静态表格转化一段已有的表格元素无需配置数据接口,在JS中指定表格元素,并简单地给表头加上自定义属性即可

方法渲染

其实这是“自动化渲染”的手动模式,本质类似,只是“方法级渲染”将基础参数的设定放在了JS代码中,且原始的 table 标签只需要一个 选择器

 

HTMLcode


<table id="demo" lay-filter="test"></table>
 

JavaScriptcode

var table = layui.table;

//执行渲染
table.render({
elem: '#demo' //指定原始表格元素选择器(推荐id选择器)
,height: 315 //容器高度
,cols: [{}] //设置表头
//,…… //更多参数参考右侧目录:基本参数选项
});

事实上我们更推荐采用“方法级渲染”的做法,其最大的优势在于你可以脱离HTML文件,而专注于JS本身。尤其对于项目的频繁改动及发布,其便捷性会体现得更为明显。而究竟它与“自动化渲染”的方式谁更简单,也只能由各位猿猿们自行体味了。

备注:table.render()方法返回一个对象:var tableIns = table.render(options),可用于对当前表格进行“重载”等操作,详见目录:表格重载

自动渲染

所谓的自动渲染,即:在一段 table 容器中配置好相应的参数,由 table 模块内部自动对其完成渲染,而无需你写初始的渲染方法。其特点在上文也有阐述。你需要关注的是以下三点:

1) 带有 class="layui-table" 的 <table> 标签。
2) 对标签设置属性 lay-data="" 用于配置一些基础参数
3) 在 <th> 标签中设置属性lay-data=""用于配置表头信息

按照上述的规范写好table原始容器后,只要你加载了layui 的 table 模块,就会自动对其建立动态的数据表格。下面是一个示例:

 

</>code

<table class="layui-table" lay-data="{height:315, url:'/demo/table/user/', 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'}">职业</th>
<th lay-data="{field:'wealth', sort: true}">财富</th>
</tr>
</thead>
</table>

转换静态表格

假设你的页面已经存在了一段有内容的表格,它由原始的table标签组成,这时你需要赋予它一些动态元素,比如拖拽调整列宽?比如排序等等?那么你同样可以很轻松地去实现。如下所示:

昵称积分签名
贤心166人生就像是一场修行a
贤心288人生就像是一场修行b
贤心333人生就像是一场修行c

转换上述表格

通过上面的小例子,你已经初步见识了这一功能的实际意义。尝试在你的静态表格的 th 标签中加上 lay-data="" 属性,代码如下:

 

HTMLcode

<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>

然后执行用于转换表格的JS方法,就可以达到目的了:

 

JavaScriptcode

var table = layui.table;

//转换静态表格
table.init('demo', {
height: 315 //设置高度
,limit: 10 //注意:请务必确保 limit 参数(默认:10)是与你服务端限定的数据条数一致
//支持所有基础参数
});

在前面的“方法渲染”和“自动渲染”两种方式中,你的数据都来源于异步的接口,这可能并不利于所谓的seo(当然是针对于前台页面)。而在这里,你的数据已和页面同步输出,却仍然可以转换成动态表格,是否感受到一丝惬意呢?

基础参数一览表

基础参数并非所有都要出现,有必选也有可选,结合你的实际需求自由设定。基础参数一般出现在以下几种场景中:

 

</>code

  1. 场景一:下述方法中的键值即为基础参数项
    table.render({
    height: 300
    ,url: '/api/data'
    });

  2. 场景二:下述 lay-data 里面的内容即为基础参数项,切记:值要用单引号
    <table lay-data="{height:300, url:'/api/data'}" lay-filter="demo"> …… </table>
  3. 更多场景:下述 options 即为含有基础参数项的对象
    > table.init('filter', options); //转化静态表格
    > var tableObj = table.render({});
    tableObj.reload(options); //重载表格

下面是目前 table 模块所支持的全部参数一览表,我们对重点参数进行了的详细说明,你可以点击下述表格最右侧的“示例”去查看

参数类型说明示例值
elemString/DOM指定原始 table 容器的选择器或 DOM,方法渲染方式必填"#demo"
colsArray设置表头。值是一个二维数组。方法渲染方式必填详见表头参数
url(等)-异步数据接口相关参数。其中 url 参数为必填项详见异步参数
toolbarString/DOM/Boolean开启表格头部工具栏区域,该参数支持四种类型值:
  • toolbar: '#toolbarDemo' //指向自定义工具栏模板选择器
  • toolbar: '<div>xxx</div>' //直接传入工具栏模板字符
  • toolbar: true //仅开启工具栏,不显示左侧模板
  • toolbar: 'default' //让工具栏左侧显示默认的内置模板

注意:
1. 该参数为 layui 2.4.0 开始新增。
2. 若需要“列显示隐藏”、“导出”、“打印”等功能,则必须开启该参数

false
defaultToolbarArray该参数可自由配置头部工具栏右侧的图标按钮详见头工具栏图标
widthNumber设定容器宽度。table容器的默认宽度是跟随它的父元素铺满,你也可以设定一个固定值,当容器中的内容超出了该宽度时,会自动出现横向滚动条。1000
heightNumber/String设定容器高度详见height
cellMinWidthNumber(layui 2.2.1 新增)全局定义所有常规单元格的最小宽度(默认:60),一般用于列宽自动分配的情况。其优先级低于表头参数中的 minWidth100
doneFunction数据渲染完的回调。你可以借此做一些其它的操作详见 done 回调
errorFunction数据请求失败的回调,返回两个参数:错误对象、内容
layui 2.6.0 新增
-
dataArray直接赋值数据。既适用于只展示一页数据,也非常适用于对一段已知数据进行多页展示。[{}, {}, {}, {}, …]
escapeBoolean是否开启 xss 字符过滤(默认 false)layui 2.6.8 新增true
totalRowBoolean/String是否开启合计行区域false
pageBoolean/Object开启分页(默认:false)。支持传入一个对象,里面可包含 laypage 组件所有支持的参数(jump、elem除外){theme: '#c00'}
limitNumber每页显示的条数(默认 10)。值需对应 limits 参数的选项。
注意:优先级低于 page 参数中的 limit 参数
30
limitsArray每页条数的选择项,默认:[10,20,30,40,50,60,70,80,90]。
注意:优先级低于 page 参数中的 limits 参数
[30,60,90]
loadingBoolean是否显示加载条(默认 true)。若为 false,则在切换分页时,不会出现加载条。该参数只适用于 url 参数开启的方式false
titleString定义 table 的大标题(在文件导出等地方会用到)"用户表"
textObject自定义文本,如空数据时的异常提示等。详见自定义文本
autoSortBoolean默认 true,即直接由 table 组件在前端自动处理排序。
若为 false,则需自主排序,即由服务端返回排序好的数据
详见事件排序
initSortObject初始排序状态。
用于在数据表格渲染完毕时,默认按某个字段排序。
详见初始排序
idString设定容器唯一 id。id 是对表格的数据操作方法上是必要的传递条件,它是表格容器的索引,你在下文诸多地方都将会见识它的存在。

另外,若该参数未设置,则默认从 <table id="test"></table> 中的 id 属性值中获取。
test
skin(等)-设定表格各种外观、尺寸等详见表格风格

cols - 表头参数一览表

相信我,在你还尚无法驾驭 layui table 的时候,你的所有焦点都应放在这里,它带引领你完成许多可见和不可见甚至你无法想象的工作。如果你采用的是方法渲染,cols 是一个二维数组,表头参数设定在数组内;如果你采用的自动渲染,表头参数的设定应放在 <th> 标签上

参数类型说明示例值
fieldString设定字段名。非常重要,且是表格数据列的唯一标识username
titleString设定标题名称用户名
widthNumber/String设定列宽,若不填写,则自动分配;若填写,则支持值为:数字、百分比。
请结合实际情况,对不同列做不同设定。
200
30%
minWidthNumber局部定义当前常规单元格的最小宽度(默认:60),一般用于列宽自动分配的情况。其优先级高于基础参数中的 cellMinWidth100
typeString设定列类型。可选值有:
  • normal(常规列,无需设定)
  • checkbox(复选框列)
  • radio(单选框列,layui 2.4.0 新增)
  • numbers(序号列)
  • space(空列)
任意一个可选值
LAY_CHECKEDBoolean是否全选状态(默认:false)。必须复选框列开启后才有效,如果设置 true,则表示复选框默认全部选中。true
fixedString固定列。可选值有:left(固定在左)、right(固定在右)。一旦设定,对应的列将会被固定在左或右,不随滚动条而滚动。
注意:如果是固定在左,该列必须放在表头最前面;如果是固定在右,该列必须放在表头最后面。
left(同 true)
right
hideBoolean是否初始隐藏列,默认:false。layui 2.4.0 新增true
totalRowBoolean/String
  • 是否开启该列的自动合计功能,默认:false。
  • 当开启时,则默认由前端自动合计当前行数据。从 layui 2.5.6 开始: 若接口直接返回了合计行数据,则优先读取接口合计行数据,格式如下:
 

</>code

  1. {
  2. "code": 0,
  3. "totalRow": {
  4. "score": "666"
  5. ,"experience": "999"
  6. },
  7. "data": [{}, {}],
  8. "msg": "",
  9. "count": 1000
  10. }

如上,在 totalRow 中返回所需统计的列字段名和值即可。
另外,totalRow 字段同样可以通过 parseData 回调来解析成为 table 组件所规定的数据格式。

  • 从 layui 2.6.3 开始,如果 totalRow 为一个 string 类型,则可解析为合计行的动态模板,如:
 

</>code

  1. totalRow: '{{ d.TOTAL_NUMS }} 单位'
  2. //还比如只取整:'{{ parseInt(d.TOTAL_NUMS) }}'
true
totalRowTextString用于显示自定义的合计文本。layui 2.4.0 新增"合计:"
sortBoolean是否允许排序(默认:false)。如果设置 true,则在对应的表头显示排序icon,从而对列开启排序功能。

注意:不推荐对值同时存在“数字和普通字符”的列开启排序,因为会进入字典序比对。比如:'贤心' > '2' > '100',这可能并不是你想要的结果,但字典序排列算法(ASCII码比对)就是如此。

true
unresizeBoolean是否禁用拖拽列宽(默认:false)。默认情况下会根据列类型(type)来决定是否禁用,如复选框列,会自动禁用。而其它普通列,默认允许拖拽列宽,当然你也可以设置 true 来禁用该功能。false
editString单元格编辑类型(默认不开启)目前只支持:text(输入框)text
eventString自定义单元格点击事件名,以便在 tool 事件中完成对该单元格的业务处理任意字符
styleString自定义单元格样式。即传入 CSS 样式background-color: #5FB878; color: #fff;
alignString单元格排列方式。可选值有:left(默认)、center(居中)、right(居右)center
colspanNumber单元格所占列数(默认:1)。一般用于多级表头3
rowspanNumber单元格所占行数(默认:1)。一般用于多级表头2
templetString自定义列模板,模板遵循 laytpl 语法。这是一个非常实用的功能,你可借助它实现逻辑处理,以及将原始数据转化成其它格式,如时间戳转化为日期字符等详见自定义模板
toolbarString绑定工具条模板。可在每行对应的列中出现一些自定义的操作性按钮详见行工具事件

下面是一些方法渲染和自动渲染的配置方式:

 

</>code

//方法渲染:
table.render({
cols: [[ //标题栏
{checkbox: true}
,{field: 'id', title: 'ID', width: 80}
,{field: 'username', title: '用户名', width: 120}
]]
});

它等价于自动渲染:

<table class="layui-table" lay-data="{基础参数}" 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>

以下是一个二级表头的例子:

 

</>code

  1. JS:
    table.render({
    cols: [[ //标题栏
    {field: 'username', title: '联系人', width: 80, rowspan: 2} //rowspan即纵向跨越的单元格数
    ,{field: 'amount', title: '金额', width: 80, rowspan: 2}
    ,{align: 'center', title: '地址', colspan: 3} //colspan即横跨的单元格数,这种情况下不用设置field和width
    ], [
    {field: 'province', title: '省', width: 80}
    ,{field: 'city', title: '市', width: 120}
    ,{field: 'county', title: '详细', width: 300}
    ]]
    });
    
    它等价于:
    <table class="layui-table" lay-data="{基础参数}">
    <thead>
    <tr>
    <th lay-data="{field:'username', width:80}" rowspan="2">联系人</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}">详细</th>
    </tr>
    </thead>
    </table>

需要说明的是,table 组件支持无限极表头,你可按照上述的方式继续扩充。核心点在于 rowspan 和 colspan 两个参数的使用。

templet - 自定义列模板

类型:String,默认值:

在默认情况下,单元格的内容是完全按照数据接口返回的content原样输出的,如果你想对某列的单元格添加链接等其它元素,你可以借助该参数来轻松实现。这是一个非常实用且强大的功能,你的表格内容会因此而丰富多样。

templet 提供了三种使用方式,请结合实际场景选择最合适的一种:
  • 如果自定义模版的字符量太大,我们推荐你采用【方式一】;
  • 如果自定义模板的字符量适中,或者想更方便地调用外部方法,我们推荐你采用【方式二】;
  • 如果自定义模板的字符量很小,我们推荐你采用【方式三】

方式一:绑定模版选择器。

 

</>code

table.render({
cols: [[
{field:'title', title: '文章标题', width: 200, templet: '#titleTpl'} //这里的templet值是模板元素的选择器
,{field:'id', title:'ID', width:100}
]]
});

等价于:
<th lay-data="{field:'title', width: 200, templet: '#titleTpl'}">文章标题</th>
<th lay-data="{field:'id', width:100}">ID</th>

下述是templet对应的模板,它可以存放在页面的任意位置。模板遵循于 laytpl 语法,可读取到返回的所有数据

 

HTMLcode

<script type="text/html" id="titleTpl">
<a href="/detail/{{d.id}}" class="layui-table-link">{{d.title}}</a>
</script>
  1. 注意:上述的 {{d.id}}、{{d.title}} 是动态内容,它对应数据接口返回的字段名。除此之外,你还可以读取到以下额外字段:
    序号:{{ d.LAY_INDEX }}
    当前列的表头信息:{{ d.LAY_COL }} (layui 2.6.8 新增)
  2. 由于模板遵循 laytpl 语法(建议细读 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>

方式二:函数转义。templet 若未函数,则返回一个参数 d(包含当前行数据及特定的额外字段)。如下所示:

 

</>code

table.render({
cols: [[
{field:'title', title: '文章标题', width: 200
,templet: function(d){
console.log(d.LAY_INDEX); //得到序号。一般不常用
console.log(d.LAY_COL); //得到当前列表头配置信息(layui 2.6.8 新增)。一般不常用

//得到当前行数据,并拼接成自定义模板
return 'ID:'+ d.id +',标题:<span style="color: #c00;">'+ d.title +'</span>'
}
}
,{field:'id', title:'ID', width:100}
]]
});

方式三:直接赋值模版字符。事实上,templet 也可以直接是一段 html 内容,如:

 

</>code

templet: '<div><a href="/detail/{{d.id}}" class="layui-table-link">{{d.title}}</a></div>'

注意:这里一定要被一层 <div></div> 包裹,否则无法读取到模板

toolbar - 绑定工具条模板

类型:String,默认值:

通常你需要在表格的每一行加上 查看编辑删除 这样类似的操作按钮,而 tool 参数就是为此而生,你因此可以非常便捷地实现各种操作功能。tool 参数和 templet 参数的使用方式完全类似,通常接受的是一个选择器,也可以是一段HTML字符。

 

</>code

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 对应的模板,它可以存放在页面的任意位置:

 

HTMLcode

<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="" 是模板的关键所在,值可随意定义。

接下来我们可以借助 table模块的工具条事件,完成不同的操作功能:

 

</>code

//工具条事件
table.on('tool(test)', function(obj){ //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"
var data = obj.data; //获得当前行数据
var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
var tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)

if(layEvent === 'detail'){ //查看
//do somehing
} else if(layEvent === 'del'){ //删除
layer.confirm('真的删除行么', function(index){
obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
layer.close(index);
//向服务端发送删除指令
});
} else if(layEvent === 'edit'){ //编辑
//do something

//同步更新缓存对应的值
obj.update({
username: '123'
,title: 'xxx'
});
} else if(layEvent === 'LAYTABLE_TIPS'){
layer.alert('Hi,头部工具栏扩展的右侧图标。');
}
});

异步数据参数

数据的异步请求由以下几个参数组成:

参数名功能
url接口地址。默认会自动传递两个参数:?page=1&limit=30(该参数可通过 request 自定义)
page 代表当前页码、limit 代表每页数据量
method接口http请求类型,默认:get
where接口的其它参数。如:where: {token: 'sasasas', id: 123}
contentType发送到服务端的内容编码类型。如果你要发送 json 内容,可以设置:contentType: 'application/json'
headers接口的请求头。如:headers: {token: 'sasasas'}
parseData

数据格式解析的回调函数,用于将返回的任意数据格式解析成 table 组件规定的数据格式。

table 组件默认规定的数据格式为(参考:/demo/table/user/):

 

默认规定的数据格式code

  1. {
  2. "code": 0,
  3. "msg": "",
  4. "count": 1000,
  5. "data": [{}, {}]
  6. }

很多时候,您接口返回的数据格式并不一定都符合 table 默认规定的格式,比如:

 

假设您返回的数据格式code

  1. {
  2. "status": 0,
  3. "message": "",
  4. "total": 180,
  5. "data": {
  6. "item": [{}, {}]
  7. }
  8. }

那么你需要借助 parseData 回调函数将其解析成 table 组件所规定的数据格式

 

</>code

  1. table.render({
  2. elem: '#demp'
  3. ,url: ''
  4. ,parseData: function(res){ //res 即为原始返回的数据
  5. return {
  6. "code": res.status, //解析接口状态
  7. "msg": res.message, //解析提示文本
  8. "count": res.total, //解析数据长度
  9. "data": res.data.item //解析数据列表
  10. };
  11. }
  12. //,…… //其他参数
  13. });

该参数非常实用,系 layui 2.4.0 开始新增

request用于对分页请求的参数:page、limit重新设定名称,如:
 

</>code

  1. table.render({
  2. elem: '#demp'
  3. ,url: ''
  4. ,request: {
  5. pageName: 'curr' //页码的参数名称,默认:page
  6. ,limitName: 'nums' //每页数据量的参数名,默认:limit
  7. }
  8. //,…… //其他参数
  9. });
那么请求数据时的参数将会变为:?curr=1&nums=30
response

您还可以借助 response 参数来重新设定返回的数据格式,如:

 

</>code

  1. table.render({
  2. elem: '#demp'
  3. ,url: ''
  4. ,response: {
  5. statusName: 'status' //规定数据状态的字段名称,默认:code
  6. ,statusCode: 200 //规定成功的状态码,默认:0
  7. ,msgName: 'hint' //规定状态信息的字段名称,默认:msg
  8. ,countName: 'total' //规定数据总数的字段名称,默认:count
  9. ,dataName: 'rows' //规定数据列表的字段名称,默认:data
  10. }
  11. //,…… //其他参数
  12. });
那么上面所规定的格式为:
 

重新规定的数据格式code

  1. {
  2. "status": 200,
  3. "hint": "",
  4. "total": 1000,
  5. "rows": []
  6. }

注意:request 和 response 参数均为 layui 2.1.0 版本新增

调用示例:

 

</>code

//“方法级渲染”配置方式
table.render({ //其它参数在此省略
url: '/api/data/'
//where: {token: 'sasasas', id: 123} //如果无需传递额外参数,可不加该参数
//method: 'post' //如果无需自定义HTTP类型,可不加该参数
//request: {} //如果无需自定义请求参数,可不加该参数
//response: {} //如果无需自定义数据响应名称,可不加该参数
});

等价于(“自动化渲染”配置方式)

<table class="layui-table" lay-data="{url:'/api/data/'}" lay-filter="test"> …… </table>

done - 数据渲染完的回调

类型:Function,默认值:

无论是异步请求数据,还是直接赋值数据,都会触发该回调。你可以利用该回调做一些表格以外元素的渲染。

 

</>code

table.render({ //其它参数在此省略
done: function(res, curr, count){
//如果是异步请求数据方式,res即为你接口返回的信息。
//如果是直接赋值的方式,res即为:{data: [], count: 99} data为当前页数据、count为数据总长度
console.log(res);

//得到当前页码
console.log(curr);

//得到数据总量
console.log(count);
}
});

defaultToolbar - 头部工具栏右侧图标

类型:Array,默认值:["filter","exports","print"]

该参数可自由配置头部工具栏右侧的图标按钮,值为一个数组,支持以下可选值:

  • filter: 显示筛选图标
  • exports: 显示导出图标
  • print: 显示打印图标

可根据值的顺序显示排版图标,如:

defaultToolbar: ['filter', 'print', 'exports']

另外你还可以无限扩展图标按钮(layui 2.5.5 新增):

 

</>code

table.render({ //其它参数在此省略
defaultToolbar: ['filter', 'print', 'exports', {
title: '提示' //标题
,layEvent: 'LAYTABLE_TIPS' //事件名,用于 toolbar 事件中使用
,icon: 'layui-icon-tips' //图标类名
}]
});

扩展的图标可通过 toolbar 事件回调(详见行工具事件),其中 layEvent 的值会在事件的回调参数中返回,以便区分不同的触发动作。

text - 自定义文本

类型:Object

table 模块会内置一些默认的文本信息,如果想修改,你可以设置以下参数达到目的。

 

</>code

table.render({ //其它参数在此省略
text: {
none: '暂无相关数据' //默认:无数据。
}
});

initSort - 初始排序

类型:Object,默认值:

用于在数据表格渲染完毕时,默认按某个字段排序。注:该参数为 layui 2.1.1 新增

 

</>code

//“方法级渲染”配置方式
table.render({ //其它参数在此省略
initSort: {
field: 'id' //排序字段,对应 cols 设定的各字段名
,type: 'desc' //排序方式 asc: 升序、desc: 降序、null: 默认排序
}
});

等价于(“自动化渲染”配置方式)
<table class="layui-table" lay-data="{initSort:{field:'id', type:'desc'}}" lay-filter="test"> …… </table>

height - 设定容器高度

类型:Number/String,可选值如下:

可选值说明示例
不填写默认情况。高度随数据列表而适应,表格容器不会出现纵向滚动条-
固定值设定一个数字,用于定义容器高度,当容器中的内容超出了该高度时,会自动出现纵向滚动条height: 315
full-差值高度将始终铺满,无论浏览器尺寸如何。这是一个特定的语法格式,其中 full 是固定的,而 差值 则是一个数值,这需要你来预估,比如:表格容器距离浏览器顶部和底部的距离“和”
PS:该功能为 layui 2.1.0 版本中新增
height: 'full-20'

示例:

 

</>code

//“方法级渲染”配置方式
table.render({ //其它参数在此省略
height: 315 //固定值
});
table.render({ //其它参数在此省略
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>

设定表格外观

控制表格外观的主要由以下参数组成:

参数名可选值备注
skinline (行边框风格)
row (列边框风格)
nob (无边框风格)
用于设定表格风格,若使用默认风格不设置该属性即可
eventrue/false若不开启隔行背景,不设置该参数即可
sizesm (小尺寸)
lg (大尺寸)
用于设定表格尺寸,若使用默认尺寸不设置该属性即可
 

</>code

//“方法级渲染”配置方式
table.render({ //其它参数在此省略
skin: 'line' //行边框风格
,even: true //开启隔行背景
,size: 'sm' //小尺寸的表格
});

等价于(“自动化渲染”配置方式)

<table class="layui-table" lay-data="{skin:'line', even:true, size:'sm'}" lay-filter="test"> …… </table>

基础方法

基础用法是table模块的关键组成部分,目前所开放的所有方法如下:

 

</>code

  1. > table.set(options); //设定全局默认参数。options即各项基础参数
  2. > table.on('event(filter)', callback); //事件。event为内置事件名(详见下文),filter为容器lay-filter设定的值
  3. > table.init(filter, options); //filter为容器lay-filter设定的值,options即各项基础参数。例子见:转换静态表格
  4. > table.checkStatus(id); //获取表格选中行(下文会有详细介绍)。id 即为 id 参数对应的值
  5. > table.render(options); //用于表格方法级渲染,核心方法。应该不用再过多解释了,详见:方法级渲染
  6. > table.reload(id, options, deep); //表格重载
  7. > table.resize(id); //重置表格尺寸
  8. > table.exportFile(id, data, type); //导出数据
  9. > table.getData(id); //用于获取表格当前页的所有行数据(layui 2.6.0 开始新增

获取选中行

该方法可获取到表格所有的选中行相关数据
语法:table.checkStatus('ID'),其中 ID 为基础参数 id 对应的值(见:设定容器唯一ID),如:

 

渲染方式code

  1. 【自动化渲染】
    <table class="layui-table" lay-data="{id: 'idTest'}"> …… </table>
  2. 【方法渲染】
    table.render({ //其它参数省略
    id: 'idTest'
    });

调用code

  1. var checkStatus = table.checkStatus('idTest'); //idTest 即为基础参数 id 对应的值
  2. console.log(checkStatus.data) //获取选中行的数据
  3. console.log(checkStatus.data.length) //获取选中行数量,可作为是否有选中行的条件
  4. console.log(checkStatus.isAll ) //表格是否全选

重置表格尺寸

该方法可重置表格尺寸和结构,其内部完成了:固定列高度平铺动态分配列宽容器滚动条宽高补丁 等操作。它一般用于特殊情况下(如“非窗口 resize”导致的表格父容器宽度变化而引发的列宽适配异常),以保证表格在此类特殊情况下依旧能友好展示。

语法:table.resize('ID'),其中 ID 为基础参数 id 对应的值(见:设定容器唯一ID),如:

 

</>code

table.render({ //其它参数省略
,elem: '#demo'
//,…… //其它参数
,id: 'idTest'
});
  1. //执行表格“尺寸结构”的重置,一般写在对应的事件中

        table.resize('idTest'); 

表格重载

很多时候,你需要对表格进行重载。比如数据全局搜索。以下方法可以帮你轻松实现这类需求(可任选一种)。

语法说明适用场景
table.reload(ID, options, deep)参数 ID 即为基础参数id对应的值,见:设定容器唯一ID
参数 options 即为各项基础参数
参数 deep:是否采用深度重载(即参数深度克隆,也就是重载时始终携带初始时及上一次重载时的参数),默认 false
注意:deep 参数为 layui 2.6.0 开始新增。
所有渲染方式
tableIns.reload(options, deep)参数同上
tableIns 可通过 var tableIns = table.render() 得到
仅限方法级渲染
请注意:如果你在 2.6.0 之前版本已经习惯深度重载模式的,现在请在第三个参数中,加上 true,如:

table.reload(ID, options, true); //这样就跟 v2.5.7 及之前版本处理机制完全一样。或者您也可以像下面这样做:
 
 

</>code

  1. //由于 2.6.0 之前的版本是采用深重载,
  2. //所以如果您之前真实采用了深重载机制,那么建议将以下代码放入您的全局位置,从而可对老项目起到兼容作用
  3. var tableReload = table.reload;
  4. table.reload = function(){
  5. var args = [];
  6. layui.each(arguments, function(index, item){
  7. args.push(item);
  8. });
  9. args[2] === undefined && (args[2] = true);
  10. return tableReload.apply(null, args);
  11. };
  12. //但如果你之前没有采用深重载机制,也可以不放。不放甚至可以解决你之前因为多次 reload 而带来的各种参数重叠问题

重载示例:

 

示例1:自动化渲染的重载code

  1. 【HTML】
    <table class="layui-table" lay-data="{id: 'idTest'}"> …… </table>
  2. 【JS】
    table.reload('idTest', {
    url: '/api/table/search'
    ,where: {} //设定异步数据接口的额外参数
    //,height: 300
    });

示例2:方法级渲染的重载code

//所获得的 tableIns 即为当前容器的实例
var tableIns = table.render({
elem: '#id'
,cols: [] //设置表头
,url: '/api/data' //设置异步接口
,id: 'idTest'
});

//这里以搜索为例
tableIns.reload({
where: { //设定异步数据接口的额外参数,任意设
aaaaaa: 'xxx'
,bbb: 'yyy'
//…
}
,page: {
curr: 1 //重新从第 1 页开始
}
});
//上述方法等价于
table.reload('idTest', {
where: { //设定异步数据接口的额外参数,任意设
aaaaaa: 'xxx'
,bbb: 'yyy'
//…
}
,page: {
curr: 1 //重新从第 1 页开始
}
}); //只重载数据

注意:这里的表格重载是指对表格重新进行渲染,包括数据请求和基础参数的读取

导出任意数据

尽管 table 的工具栏内置了数据导出按钮,但有时你可能需要通过方法去导出任意数据,那么可以借助以下方法:
语法:table.exportFile(id, data, type)

 

</>code

var ins1 = table.render({
elem: '#demo'
,id: 'test'
//,…… //其它参数
})

//将上述表格示例导出为 csv 文件
table.exportFile(ins1.config.id, data); //data 为该实例中的任意数量的数据

事实上,该方法也可以不用依赖 table 的实例,可直接导出任意数据:

 

</>code

table.exportFile(['名字','性别','年龄'], [
['张三','男','20'],
['李四','女','18'],
['王五','女','19']
], 'csv'); //默认导出 csv,也可以为:xls

事件

语法:table.on('event(filter)', callback);
注:event 为内置事件名,filter 为容器 lay-filter 设定的值
目前所支持的所有事件见下文

默认情况下,事件所触发的是全部的table模块容器,但如果你只想触发某一个容器,使用事件过滤器即可。
假设原始容器为:<table class="layui-table" lay-filter="test"></table> 那么你的事件写法如下:

 

</>code

//以复选框事件为例
table.on('checkbox(test)', function(obj){
console.log(obj)
});

触发头部工具栏事件

点击头部工具栏区域设定了属性为 lay-event="" 的元素时触发(该事件为 layui 2.4.0 开始新增)。如:

</>code

  1. 原始容器
    <table id="demo" lay-filter="test"></table>
  2. 工具栏模板:
    <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 调用:
    table.render({
    elem: '#demo'
    ,toolbar: '#toolbarDemo'
    //,…… //其他参数
    });
    
    //触发事件
    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>

触发复选框选择

点击复选框时触发,回调函数返回一个 object 参数:

 

</>code

table.on('checkbox(test)', function(obj){
console.log(obj); //当前行的一些常用操作集合
console.log(obj.checked); //当前是否选中状态
console.log(obj.data); //选中行的相关数据
console.log(obj.type); //如果触发的是全选,则为:all,如果触发的是单选,则为:one
});

触发单选框选择

点击表格单选框时触发,回调函数返回一个 object 参数,携带的成员如下:

 

</>code

table.on('radio(test)', function(obj){ //test 是 table 标签对应的 lay-filter 属性
console.log(obj); //当前行的一些常用操作集合
console.log(obj.checked); //当前是否选中状态
console.log(obj.data); //选中行的相关数据
});

触发单元格编辑

单元格被编辑,且值发生改变时触发,回调函数返回一个object参数,携带的成员如下:

 

</>code

table.on('edit(test)', function(obj){ //注:edit是固定事件名,test是table原始容器的属性 lay-filter="对应的值"
console.log(obj.value); //得到修改后的值
console.log(obj.field); //当前编辑的字段名
console.log(obj.data); //所在行的所有相关数据
});

触发行单双击事件

点击或双击行时触发。该事件为 layui 2.4.0 开始新增

 

</>code

//触发行单击事件
table.on('row(test)', function(obj){
console.log(obj.tr) //得到当前行元素对象
console.log(obj.data) //得到当前行数据
//obj.del(); //删除当前行
//obj.update(fields) //修改当前行数据
});

//触发行双击事件
table.on('rowDouble(test)', function(obj){
//obj 同上
});

触发行中工具条点击事件

具体用法见:绑定工具条

触发排序切换

点击表头排序时触发,它通用在基础参数中设置 autoSort: false 时使用,以完成服务端的排序,而不是默认的前端排序。该事件的回调函数返回一个 object 参数,携带的成员如下:

 

</>code

//禁用前端自动排序,以便由服务端直接返回排序好的数据
table.render({
elem: '#id'
,autoSort: false //禁用前端自动排序。注意:该参数为 layui 2.4.4 新增
//,… //其它参数省略
});

//触发排序事件
table.on('sort(test)', function(obj){ //注:sort 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"
console.log(obj.field); //当前排序的字段名
console.log(obj.type); //当前排序类型:desc(降序)、asc(升序)、null(空对象,默认排序)
console.log(this); //当前排序的 th 对象

//尽管我们的 table 自带排序功能,但并没有请求服务端。
//有些时候,你可能需要根据当前排序的字段,重新向服务端发送请求,从而实现服务端排序,如:
table.reload('idTest', {
initSort: obj //记录初始排序,如果不设的话,将无法标记表头的排序状态。
,where: { //请求参数(注意:这里面的参数可任意定义,并非下面固定的格式)
field: obj.field //排序字段
,order: obj.type //排序方式
}
});

layer.msg('服务端排序。order by '+ obj.field + ' ' + obj.type);
});

 

六、表单模块文档 - layui.form

我们通常会在最常用的模块上耗费更多的精力,用尽可能简单的方式诠释 layui 所带来的便捷性。显而易见,form 是我们非常看重的一块。于是它试图用一贯极简的姿态,去捕获你对它的深深青睐。寄托在原始表单元素上的属性设定,及其全自动的初始渲染,和基于事件驱动的接口书写方式,会让你觉得,传统模式下的组件调用形式,也可以是那样的优雅、简单。然而文字的陈述始终是苍白的,所以用行动慢慢感受 layui.form 给你的项目带来的效率提升吧。

模块加载名称:form

使用

layui 针对各种表单元素做了较为全面的UI支持,你无需去书写那些 UI 结构,你只需要写 HTML 原始的 input、select、textarea 这些基本的标签即可。我们在 UI 上的渲染只要求一点,你必须给表单体系所在的父元素加上class="layui-form",一切的工作都会在你加载完form模块后,自动完成。如下是一个最基本的例子:

 

layui.form小例子code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layui.form小例子</title>
<link rel="stylesheet" href="layui.css" media="all">
</head>
<body>
<form class="layui-form"> <!-- 提示:如果你不想用form,你可以换成div等任何一个普通元素 -->
<div class="layui-form-item">
<label class="layui-form-label">输入框</label>
<div class="layui-input-block">
<input type="text" name="" placeholder="请输入" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">下拉选择框</label>
<div class="layui-input-block">
<select name="interest" lay-filter="aihao">
<option value="0">写作</option>
<option value="1">阅读</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">复选框</label>
<div class="layui-input-block">
<input type="checkbox" name="like[write]" title="写作">
<input type="checkbox" name="like[read]" title="阅读">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">开关关</label>
<div class="layui-input-block">
<input type="checkbox" lay-skin="switch">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">开关开</label>
<div class="layui-input-block">
<input type="checkbox" checked lay-skin="switch">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">单选框</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="0" title="男">
<input type="radio" name="sex" value="1" title="女" checked>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">请填写描述</label>
<div class="layui-input-block">
<textarea placeholder="请输入内容" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="*">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
<!-- 更多表单结构排版请移步文档左侧【页面元素-表单】一项阅览 -->
</form>
<script src="layui.js"></script>
<script>
layui.use('form', function(){
var form = layui.form;

//各种基于事件的操作,下面会有进一步介绍
});
</script>
</body>
</html>

正如你上述看到的,你必须放入 layui 所规范的元素结构,form 模块才会对其进行重置渲染。值得注意的是,在具体的每一块表单元素中,你仍是像往日一样写 input 等标签即可。另外,我们对我们所规范的结构进行了响应式的支持,而针对一些不同的表单排版,比如行内表单,你也只需要设定我们所定义好的 class 即可。关于这一块,你可以移步页面元素的表单文档中做详细了解。而事实上你的大部分焦点可能也在那里,但当前这篇文档主要还是介绍 form 整体模块。

更新渲染

有些时候,你的有些表单元素可能是动态插入的。这时 form 模块 的自动化渲染是会对其失效的。虽然我们没有双向绑定机制(因为我们叫经典模块化框架,偷笑.gif) 但没有关系,你只需要执行 form.render(type, filter); 方法即可。

第一个参数:type,为表单的 type 类型,可选。默认对全部类型的表单进行一次更新。可局部刷新的 type 如下表:

参数(type)值描述
select刷新select选择框渲染
checkbox刷新checkbox复选框(含开关)渲染
radio刷新radio单选框框渲染
 

例子code

  1. form.render(); //更新全部
  2. form.render('select'); //刷新select选择框渲染
  3. //……

第二个参数:filter,为 class="layui-form" 所在元素的 lay-filter="" 的值。你可以借助该参数,对表单完成局部更新。

 

例子code

  1. 【HTML】
    <div class="layui-form" lay-filter="test1">
    …
    </div>
    
    <div class="layui-form" lay-filter="test2">
    …
    </div>

  2. 【JavaScript】
    form.render(null, 'test1'); //更新 lay-filter="test1" 所在容器内的全部表单状态
    form.render('select', 'test2'); //更新 lay-filter="test2" 所在容器内的全部 select 状态
    //……

预设元素属性

事实上在使用表单时,你的一半精力可能会在元素本身上。所以我们把一些基础属性的配置恰恰安放在了标签本身上。如:

 

</>code

<input type="text" lay-verify="email">
<input type="checkbox" checked lay-skin="switch" lay-filter="encrypt" title="是否加密">
<button lay-submit>提交</button>

上述的lay-verifylay-skinlay-filterlay-submit神马的都是我们所说的预设的元素属性,他们可以使得一些交互操作交由form模块内部、或者你来借助form提供的JS接口精确控制。目前我们可支持的属性如下表所示:

属性名属性值说明
title任意字符设定元素名称,一般用于checkbox、radio框
lay-skinswitch(开关风格) primary(原始风格)定义元素的风格,目前只对 checkbox 元素有效,可将其转变为开关样式
lay-ignore任意字符或不设值是否忽略元素美化处理。设置后,将不会对该元素进行初始化渲染,即保留系统风格
lay-filter任意字符事件过滤器,主要用于事件的精确匹配,跟选择器是比较类似的。其实它并不私属于form模块,它在 layui 的很多基于事件的接口中都会应用到。
lay-verifyrequired(必填项)
phone(手机号)
email(邮箱)
url(网址)
number(数字)
date(日期)
identity(身份证)
自定义值
同时支持多条规则的验证,格式:lay-verify="验证A|验证B"
如:lay-verify="required|phone|number"

另外,除了我们内置的校验规则,你还可以给他设定任意的值,比如lay-verify="pass",那么你就需要借助form.verify()方法对pass进行一个校验规则的定义。详见表单验证
lay-verTypetips(吸附层)
alert(对话框)
msg(默认)
用于定义异常提示层模式。
lay-reqText任意字符用于自定义必填项(即设定了 lay-verify="required" 的表单)的提示文本
注意:该功能为 layui 2.5.0 新增
lay-submit无需填写值绑定触发提交的元素,如button

事件触发

语法:form.on('event(过滤器值)', callback);

form模块在 layui 事件机制中注册了专属事件,所以当你使用layui.onevent()自定义模块事件时,请勿占用form名。form支持的事件如下:

event描述
select触发select下拉选择事件
checkbox触发checkbox复选框勾选事件
switch触发checkbox复选框开关事件
radio触发radio单选框事件
submit触发表单提交事件

默认情况下,事件所触发的是全部的form模块元素,但如果你只想触发某一个元素,使用事件过滤器即可。
如:<select lay-filter="test"></select>

 

</>code

form.on('select(test)', function(data){
console.log(data);
});

触发select选择

下拉选择框被选中时触发,回调函数返回一个object参数,携带两个成员:

 

语法code

form.on('select(filter)', function(data){
console.log(data.elem); //得到select原始DOM对象
console.log(data.value); //得到被选中的值
console.log(data.othis); //得到美化后的DOM对象
});

请注意:如果你想触发所有的select,去掉过滤器(filter)即可。下面将不再对此进行备注。

触发checkbox复选

复选框点击勾选时触发,回调函数返回一个object参数,携带两个成员:

 

语法code

form.on('checkbox(filter)', function(data){
console.log(data.elem); //得到checkbox原始DOM对象
console.log(data.elem.checked); //是否被选中,true或者false
console.log(data.value); //复选框value值,也可以通过data.elem.value得到
console.log(data.othis); //得到美化后的DOM对象
});

触发switch开关

开关被点击时触发,回调函数返回一个object参数,携带两个成员:

 

语法code

form.on('switch(filter)', function(data){
console.log(data.elem); //得到checkbox原始DOM对象
console.log(data.elem.checked); //开关是否开启,true或者false
console.log(data.value); //开关value值,也可以通过data.elem.value得到
console.log(data.othis); //得到美化后的DOM对象
});

触发radio单选

radio单选框被点击时触发,回调函数返回一个object参数,携带两个成员:

 

语法code

form.on('radio(filter)', function(data){
console.log(data.elem); //得到radio原始DOM对象
console.log(data.value); //被点击的radio的value值
});

触发submit提交

按钮点击或者表单被执行提交时触发,其中回调函数只有在验证全部通过后才会进入,回调返回三个成员:

 

语法code

form.on('submit(*)', function(data){
console.log(data.elem) //被执行事件的元素DOM对象,一般为button对象
console.log(data.form) //被执行提交的form对象,一般在存在form标签时才会返回
console.log(data.field) //当前容器的全部表单字段,名值对形式:{name: value}
return false; //阻止表单跳转。如果需要表单跳转,去掉这段即可。
});

再次温馨提示:上述的submit(*)中的 * 号为事件过滤器的值,是在你绑定执行提交的元素时设定的,如:

 

</>code

<button lay-submit lay-filter="*">提交</button>

你可以把*号换成任意的值,如:lay-filter="go",但触发事件时也要改成 form.on('submit(go)', callback);

表单赋值 / 取值

语法:form.val('filter', object);

用于给指定表单集合的元素赋值和取值。如果 object 参数存在,则为赋值;如果 object 参数不存在,则为取值。
注:其中「取值」功能为 layui 2.5.5 开始新增

 

</>code

//给表单赋值
form.val("formTest", { //formTest 即 class="layui-form" 所在元素属性 lay-filter="" 对应的值
"username": "贤心" // "name": "value"
,"sex": "女"
,"auth": 3
,"check[write]": true
,"open": false
,"desc": "我爱layui"
});

//获取表单区域所有值
var data1 = form.val("formTest");

第二个参数中的键值是表单元素对应的 name 和 value

表单验证

我们对表单的验证进行了非常巧妙的支持,大多数时候你只需要在表单元素上加上 lay-verify="" 属性值即可。如:

 

</>code

<input type="text" lay-verify="email">

还同时支持多条规则的验证,如下:

<input type="text" lay-verify="required|phone|number">

上述对输入框定义了一个邮箱规则的校验,它会在 form 模块内部完成。目前我们内置的校验支持见上文的:预设元素属性

除了内置的校验规则外,你还可以自定义验证规则,通常对于比较复杂的校验,这是非常有必要的。

 

语法code

form.verify({
username: function(value, item){ //value:表单的值、item:表单的DOM对象
if(!new RegExp("^[a-zA-Z0-9_\u4e00-\u9fa5\\s·]+$").test(value)){
return '用户名不能有特殊字符';
}
if(/(^\_)|(\__)|(\_+$)/.test(value)){
return '用户名首尾不能出现下划线\'_\'';
}
if(/^\d+\d+\d$/.test(value)){
return '用户名不能全为数字';
}

//如果不想自动弹出默认提示框,可以直接返回 true,这时你可以通过其他任意方式提示(v2.5.7 新增)
if(value === 'xxx'){
alert('用户名不能为敏感词');
return true;
}
}

//我们既支持上述函数式的方式,也支持下述数组的形式
//数组的两个值分别代表:[正则匹配、匹配不符时的提示文字]
,pass: [
/^[\S]{6,12}$/
,'密码必须6到12位,且不能出现空格'
]
});

当你自定义了类似上面的验证规则后,你只需要把 key 赋值给输入框的 lay-verify 属性即可:

 

</>code

<input type="text" lay-verify="username" placeholder="请输入用户名">
<input type="password" lay-verify="pass" placeholder="请输入密码">

 

七、图片/文件上传 - layui.upload

上传模块自 layui 2.0 的版本开始,进行了全面重写,这使得它不再那么单一,它所包含的不仅是更为强劲的功能,还有灵活的 UI。任何元素都可以作为上传组件来调用,譬如按钮、图片、普通的 DIV 等等,而不再是一个单调的 file 文件域。

模块加载名称:upload

快速使用

一切从小试牛刀开始。通常情况下,我们上传文件是借助 type="file" 的 input 标签来完成的,但非常遗憾的是,它不能很好地与其它表单元素并存,所以我们常常要单独为它做一个业务层面的“异步上传”,即先让图片上传,再和其它表单一起提交保存。下面是一个小示例:

上传图片

这原本只是一个普通的 button,正是 upload 模块赋予了它“文件选择”的特殊技能。当然,你还可以随意定制它的样式,而不是只局限于按钮。

 

对应的代码code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>upload模块快速使用</title>
<link rel="stylesheet" href="/static/build/layui.css" media="all">
</head>
<body>

<button type="button" class="layui-btn" id="test1">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>

<script src="/static/build/layui.js"></script>
<script>
layui.use('upload', function(){
var upload = layui.upload;

//执行实例
var uploadInst = upload.render({
elem: '#test1' //绑定元素
,url: '/upload/' //上传接口
,done: function(res){
//上传完毕回调
}
,error: function(){
//请求异常回调
}
});
});
</script>
</body>
</html>

一切看起来是那样的简单,乃至于我不得不凑一段文字来填充这一行的版面。这样好像与下文衔接起来会比较谐调的样子(自我感觉)

核心方法与基础参数选项

使用 upload 模块必须与 upload.render(options) 方法打交道,其中的 options即为基础参数,它是一个对象。

 

</>code

var upload = layui.upload; //得到 upload 对象

//创建一个上传组件
upload.render({
elem: '#id'
,url: ''
,done: function(res, index, upload){ //上传后的回调

}
//,accept: 'file' //允许上传的文件类型
//,size: 50 //最大允许上传的文件大小
//,……
})

从 layui 2.1.0 开始,允许你直接在元素上设定基础参数,如:

 

</>code

  1. 【HTML】
    <button class="layui-btn test" lay-data="{url: '/a/'}">上传图片</button>
    <button class="layui-btn test" lay-data="{url: '/b/', accept: 'file'}">上传文件</button>
  2. 【JS】
    upload.render({
    elem: '.test'
    ,done: function(res, index, upload){
    //获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
    var item = this.item;
    }
    })

更多支持的参数详见下表,合理的配置它们,应对各式各样的业务需求。

参数选项说明类型默认值
elem指向容器选择器,如:elem: '#id'。也可以是DOM对象string/object-
url服务端上传接口,返回的数据规范请详见下文string-
data请求上传接口的额外参数。如:data: {id: 'xxx'}
从 layui 2.2.6 开始,支持动态值,如:
 

</>code

  1. data: {
  2. id: function(){
  3. return $('#id').val();
  4. }
  5. }
object-
headers接口的请求头。如:headers: {token: 'sasasas'}。注:该参数为 layui 2.2.6 开始新增
accept指定允许上传时校验的文件类型,可选值有:images(图片)、file(所有文件)、video(视频)、audio(音频)stringimages
acceptMime规定打开文件选择框时,筛选出的文件类型,值为用逗号隔开的 MIME 类型列表。如:
acceptMime: 'image/*'(只显示图片文件)
acceptMime: 'image/jpg, image/png'(只显示 jpg 和 png 文件)
注:该参数为 layui 2.2.6 开始新增
stringimages
exts允许上传的文件后缀。一般结合 accept 参数类设定。假设 accept 为 file 类型时,那么你设置 exts: 'zip|rar|7z' 即代表只允许上传压缩格式的文件。如果 accept 未设定,那么限制的就是图片的文件格式stringjpg|png|gif|bmp|jpeg
auto是否选完文件后自动上传。如果设定 false,那么需要设置 bindAction 参数来指向一个其它按钮提交上传booleantrue
bindAction指向一个按钮触发上传,一般配合 auto: false 来使用。值为选择器或DOM对象,如:bindAction: '#btn'string/object-
field设定文件域的字段名stringfile
size设置文件最大可允许上传的大小,单位 KB。不支持ie8/9number0(即不限制)
multiple是否允许多文件上传。设置 true即可开启。不支持ie8/9booleanfalse
number设置同时可上传的文件数量,一般配合 multiple 参数出现。
注意:该参数为 layui 2.2.3 开始新增
number0(即不限制)
drag是否接受拖拽的文件上传,设置 false 可禁用。不支持ie8/9booleantrue
回调
choose选择文件后的回调函数。返回一个object参数,详见下文function-
before文件提交上传前的回调。返回一个object参数(同上),详见下文function-
done执行上传请求后的回调。返回三个参数,分别为:res(服务端响应信息)、index(当前文件的索引)、upload(重新上传的方法,一般在文件上传失败后使用)。详见下文function-
error执行上传请求出现异常的回调(一般为网络异常、URL 404等)。返回两个参数,分别为:index(当前文件的索引)、upload(重新上传的方法)。详见下文function-

上传接口

设定一个 URL 地址给 url 参数,用来告诉 upload 模块的服务端上传接口。像你平时使用Ajax一样。如:

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/' //必填项
,method: '' //可选项。HTTP类型,默认post
,data: {} //可选项。额外的参数,如:{id: 123, abc: 'xxx'}
});

该接口返回的相应信息(response)必须是一个标准的 JSON 格式,如:

 

Responsecode

{
"code": 0
,"msg": ""
,"data": {
"src": "http://cdn.layui.com/123.jpg"
}
}

注意1:你不一定非得按照上述格式返回,只要是合法的 JSON 字符即可。其响应信息会转化成JS对象传递给 done 回调。
注意2:如果上传后,出现文件下载框(一般为ie下),那么你需要在服务端对response的header设置 Content-Type: text/html

选择文件的回调

在文件被选择后触发,该回调会在 before 回调之前。一般用于非自动上传(即 auto: false )的场景,比如预览图片等。

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/'
,auto: false //选择文件后不自动上传
,bindAction: '#testListAction' //指向一个按钮触发上传
,choose: function(obj){
//将每次选择的文件追加到文件队列
var files = obj.pushFile();

//预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
obj.preview(function(index, file, result){
console.log(index); //得到文件索引
console.log(file); //得到文件对象
console.log(result); //得到文件base64编码,比如图片

//obj.resetFile(index, file, '123.jpg'); //重命名文件名,layui 2.3.0 开始新增

//这里还可以做一些 append 文件列表 DOM 的操作

//obj.upload(index, file); //对上传失败的单个文件重新上传,一般在某个事件中使用
//delete files[index]; //删除列表中对应的文件,一般在某个事件中使用
});
}
});

事实上这是一个非常实用的存在,可轻松应对复杂的列表文件上传管理。具体可移步到 示例 页面,里面有一个文件列表的小例子。

文件上传前的回调

在 choose 回调之后、done/error 回调之前触发。返回的参数完全类似 choose 回调。一般用于上传完毕前的loading、图片预览等。

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/'
,before: function(obj){ //obj参数包含的信息,跟 choose回调完全一致,可参见上文。
layer.load(); //上传loading
}
,done: function(res, index, upload){
layer.closeAll('loading'); //关闭loading
}
,error: function(index, upload){
layer.closeAll('loading'); //关闭loading
}
});

上传接口请求成功的回调

在上传接口请求完毕后触发,但文件不一定是上传成功的,只是接口的响应状态正常(200)。回调返回三个参数,分别为:服务端响应信息当前文件的索引重新上传的方法

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/'
,done: function(res, index, upload){
//假设code=0代表上传成功
if(res.code == 0){
//do something (比如将res返回的图片链接保存到表单的隐藏域)
}

//获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
var item = this.item;

//文件保存失败
//do something
}
});

上传请求失败的回调

当请求上传时出现异常时触发(如网络异常、404/500等)。回调返回两个参数,分别为:当前文件的索引重新上传的方法

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/'
,error: function(index, upload){
//当上传失败时,你可以生成一个“重新上传”的按钮,点击该按钮时,执行 upload() 方法即可实现重新上传
}
});

多文件上传完毕后的状态回调

只有当开启多文件时(即 multiple: true),该回调才会被触发。回调返回一个 object 类型的参数,包含一些状态数据:

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/'
,multiple: true
,allDone: function(obj){ //当文件全部被提交后,才触发
console.log(obj.total); //得到总文件数
console.log(obj.successful); //请求成功的文件数
console.log(obj.aborted); //请求失败的文件数
}
,done: function(res, index, upload){ //每个文件提交一次触发一次。详见“请求成功的回调”

}
});

文件上传进度的回调

在网速一般的情况下,大文件的上传通常需要一定时间的等待,而浏览器并不会醒目地告知你它正在努力地上传中,此时为了提升用户体验,我们可以通过该回调制作一个进度条。注:该回调为 layui 2.5.5 新增

 

</>code

upload.render({
elem: '#id'
,url: '/api/upload/'
,progress: function(n, elem, res, index){
var percent = n + '%' //获取进度百分比
element.progress('demo', percent); //可配合 layui 进度条元素使用

console.log(elem); //得到当前触发的元素 DOM 对象。可通过该元素定义的属性值匹配到对应的进度条。
console.log(res); //得到 progress 响应信息
console.log(index); //得到当前上传文件的索引,多文件上传时的进度条控制,如:
element.progress('demo-'+ index, n + '%'); //进度条
}
});

重载实例

有时你可能需要对 upload.render() 实例进行重载,通过改变一些参数(如将上传文件重置为只上传图片等场景)来重置功能。如:

 

</>code

//创建一个实例
var uploadInst = upload.render({
elem: '#id'
,url: '/api/upload/'
,size: 1024*5 //限定大小
});

//重载该实例,支持重载全部基础参数
uploadInst.reload({
accept: 'images' //只允许上传图片
,acceptMime: 'image/*' //只筛选图片
,size: 1024*2 //限定大小
});

注意:该方法为 layui 2.5.0 开始新增

重新上传

在执行 upload.render(options) 方法时,其实有返回一个实例对象,以便对完成重新上传等操作。注意:这是对当前上传队列的全局重新上传,而 choose 回调返回的 obj.upload(index, file) 方法则是对单个文件进行重新上传。如:

 

</>code

var uploadInst = upload.render({
elem: '#id'
,url: '/api/upload/'
,choose: function(obj){
obj.preview(function(index, file, result){
//对上传失败的单个文件重新上传,一般在某个事件中使用
//obj.upload(index, file);
});
}
});

//重新上传的方法,一般在某个事件中使用
//uploadInst.upload();

跨域上传

有些时候,可能会涉及到文件跨域操作,过去版本的 upload 模块最大的缺陷恰恰在于这里。而从 layui 2.0 的版本开始,我们已经对 跨域做了支持。但鉴于代码的冗余度等多方面考虑,在IE9以下版本环境中,仍然不支持跨域。其它所有版本的IE和Chrome/FireFox等高级浏览器均支持。

那么,需要你怎么做?通常来说,是借助 CORS(跨资源共享) 方案,即对接口所在的服务器设置:Access-Control-Allow-Origin 详见Google,配置起来还是挺简单的。而至于域名限制,一般是服务端程序中去做处理。这里不做过多赘述。

 

八、下拉菜单组件文档 - layui.dropdown

dropdown 是基于 layui「基础菜单」结构衍生的多功能通用下拉菜单组件,它将原本静态呈现的菜单,通过各种事件的形式触发,从而以独立面板的形式弹出。不仅可用作常见的「下拉菜单」,更可用于「右键菜单」来实现更多的交互可能。
模块加载名称: dropdown

快速使用

  • 代码
  • 演示效果
 

</>code

<button class="layui-btn" id="demo1">
下拉菜单
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>

<script>
layui.use('dropdown', function(){
var dropdown = layui.dropdown
dropdown.render({
elem: '#demo1' //可绑定在任意元素中,此处以上述按钮为例
,data: [{
title: 'menu item 1'
,id: 100
,href: '#'
},{
title: 'menu item 2'
,id: 101
,href: 'https://' //开启超链接
,target: '_blank' //新窗口方式打开
},{type: '-'},{
title: 'menu item 3'
,id: 102
,type: 'group' //菜单类型,支持:normal/group/parent/-
,child: [{
title: 'menu item 3-1'
,id: 103
},{
title: 'menu item 3-2'
,id: 104
,child: [{
title: 'menu item 3-2-1'
,id: 105
},{
title: 'menu item 3-2-2'
,id: 106
}]
},{
title: 'menu item 3-3'
,id: 107
}]
},{type: '-'},{
title: 'menu item 4'
,id: 108
},{
title: 'menu item 5'
,id: 109
,child: [{
title: 'menu item 5-1'
,id: 11111
,child: [{
title: 'menu item 5-1-1'
,id: 2111
},{
title: 'menu item 5-1-2'
,id: 3111
}]
},{
title: 'menu item 5-2'
,id: 52
}]
},{type:'-'},{
title: 'menu item 6'
,id: 6
,type: 'group'
,isSpreadItem: false
,child: [{
title: 'menu item 6-1'
,id: 61
},{
title: 'menu item 6-2'
,id: 62
}]
}]
,id: 'demo1'
//菜单被点击的事件
,click: function(obj){
console.log(obj);
layer.msg('回调返回的参数已显示再控制台');
}
});
});
</script>
菜单列表核心的数据来自于 data 参数,详细可参加右边目录「菜单列参数」

基础参数

即核心方法 dropdown.render(options) 中的 options 对应的参数:

参数说明类型默认值
elem绑定触发组件的元素。必填项String/DOM-
data菜单列数据项,其参数详见下文。必填项Array[]
trigger触发组件的事件类型。支持所有事件,如:click/hover/mousedown/contextmenu 等Stringclick
show是否初始即显示组件面板Booleanfalse
align下拉面板相对绑定元素的水平对齐方式(支持: left/center/right) v2.6.8 新增Stringleft
isAllowSpread是否允许菜单组展开收缩Booleantrue
isSpreadItem是否初始展开子菜单Booleantrue
delay延迟关闭的毫秒数。当 trigger 为 hover 时才生效Number300
className自定义组件的样式类名String-
style设置组件的 style 属性,从而定义新的样式String-
templet全局定义菜单的列表模板,添加任意 html 字符,模版将被 laytpl 组件所转义,因此可通过 {{ d.title }} 的方式得到当前菜单配置的数据。#详见String-
content自定义组件内容,从而替代默认的菜单结构String-
ready组件成功弹出后的回调,并返回两个参数,如:
 

</>JS

  1. ready: function(elemPanel, elem){
  2. console.log(elemPanel); 得到组件面板的 DOM 对象
  3. console.log(elem); 得到基础参数 elem 所绑定的元素 DOM 对象
  4. }
Function-
click菜单项被点击时的回调,并返回两个参数,如:
 

</>JS

  1. click: function(data, othis){
  2. console.log(data); 得到当前所点击的菜单项对应的数据
  3. console.log(othis); 得到当前所点击的菜单项 DOM 对象
  4. console.log(this.elem); //得到当前组件绑定的原始 DOM 对象,批量绑定中常用。
  5. }
#详细使用参见下文
Function-

菜单项参数

即上述基础参数 data 对应的参数,格式为:data: [{title: 'menu item 1', id: 1}, {}, {}]

参数说明类型默认值
title菜单标题String-
id菜单 ID。用户菜单项唯一索引Number/String-
href菜单项的超链接地址。若填写,点击菜单将直接发生跳转。Stringfalse
target菜单项超链接的打开方式,需 href 填写才生效。
一般可设为 _blank 或 _self 等
String_self
type菜单项的类型,当前支持的值如下:
normal(默认)
group(垂直菜单组)
parent(横向父子菜单)
-(分割线)
Stringnormal 或 不填
child子级菜单数据项。参数同父级,可无限嵌套。Array[]
templet自定义当前菜单项模板,优先级高于全局设定的 templet。详见下文。String-

菜单项被点击的回调

  • 代码
  • 演示效果
 

</>code

<table class="layui-table">
<tbody>
<tr>
<td>列表 1</td>
<td><button class="layui-btn layui-btn-sm demolist" data-id="111">更多操作</button></td>
</tr>
<tr>
<td>列表 2</td>
<td><button class="layui-btn layui-btn-sm demolist" data-id="222">更多操作</button></td>
</tr>
<tr>
<td>列表 3</td>
<td><button class="layui-btn layui-btn-sm demolist" data-id="333">更多操作</button></td>
</tr>
</tbody>
</table>
<script>
layui.use('dropdown', function(){
var dropdown = layui.dropdown
,$ = layui.jquery;

dropdown.render({
elem: '.demolist'
,data: [{
title: 'item 1'
,id: 'aaa'
}, {
title: 'item 2'
,id: 'bbb'
}]
,click: function(data, othis){
var elem = $(this.elem)
,listId = elem.data('id'); //表格列表的预埋数据
layer.msg('得到表格列表的 id:'+ listId +',下拉菜单 id:'+ data.id);
}
});
});
</script>

自定义菜单项模板

通过 templet 参数即可自定义菜单项模板,其字符将被 laytpl 组件所转义,因此可通过 undefined 的方式得到当前菜单配置的数据。

 

</>JS

var dropdown = layui.dropdown;

//执行菜单
dropdown.render({
elem: '#id'
,data: [{
title: '刷新'
//当设定了模板时,菜单项将优先显示模板结构;否则将默认显示标题
,templet: '<i class="layui-icon layui-icon-refresh"></i> {{d.title}}'
,id: 100
},{
title: 'menu item 2'
//该模板由「图片+标题+徽章」组成
,templet: '<img src="1.jpg" style="width: 16px;"> {{d.title}} <span class="layui-badge-dot"></span>'
,id: 101
,href: 'https://'
,target: '_blank'
},{
title: 'menu item 3' //未开启模板时,默认直接显示标题
,id: 103
}]
})

右键菜单

当参数设定为 trigger: 'contextmenu'时,即会在所绑定的元素中屏蔽默认的右键菜单,从而呈现 dropdown 组件配置的菜单。

 

</>JS

var dropdown = layui.dropdown;

//执行菜单
dropdown.render({
elem: '#demo' //在 id="demo" 的元素中触发事件。也可以直接设置为 document,从而重置整个右键菜单
,trigger: 'contextmenu' //右键事件
,data: [{
title: 'menu item 1'
,id: 1
},{
title: 'menu item 2'
,id: 'reload'
},{type:'-'},{
title: 'menu item 3'
,id: 3
,child: [{
title: 'menu item 3-1'
,id: 31
},{
title: 'menu item 3-2'
,id: 32
},{
title: 'menu item 3-3'
,id: 33
}]
},{type:'-'},{
title: 'menu item 4'
,id: 111
},{
title: 'menu item 5'
,id: 555
},{
title: 'menu item 6'
,id: 666
}]
});

 

九、穿梭框组件文档 - layui.transfer

穿梭框组件的初衷来源于 layui 社区的扩展组件平台,并且在 layui 2.5.0 的版本中开始登场。其适用的业务场景多样,不妨一试。
模块加载名称: transfer

快速使用

transfer 组件可以进行数据的交互筛选

 

layui.transfer小例子code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>穿梭框组件</title>
<link rel="stylesheet" href="../src/css/layui.css">
</head>
<body>
<div id="test1"></div>
<script src="../src/layui.js"></script>
<script>
layui.use('transfer', function(){
var transfer = layui.transfer;

//渲染
transfer.render({
elem: '#test1' //绑定元素
,data: [
{"value": "1", "title": "李白", "disabled": "", "checked": ""}
,{"value": "2", "title": "杜甫", "disabled": "", "checked": ""}
,{"value": "3", "title": "贤心", "disabled": "", "checked": ""}
]
,id: 'demo1' //定义索引
});
});
</script>
</body>
</html>

基础参数

目前 transfer 组件提供以下基础参数,可根据需要进行相应的设置

参数选项说明类型默认值
elem指向容器选择器String/Object-
title穿梭框上方标题Array['标题一', '标题二']
data数据源Array[{}, {}, …]
parseData用于对数据源进行格式解析Function详见数据源格式解析
value初始选中的数据(右侧列表)Array-
id设定实例唯一索引,用于基础方法传参使用。String-
showSearch是否开启搜索Booleanfalse
width定义左右穿梭框宽度Number200
height定义左右穿梭框高度Number340
text自定义文本,如空数据时的异常提示等。
 

</>code

  1. text: {
  2. none: '无数据' //没有数据时的文案
  3. ,searchNone: '无匹配数据' //搜索无匹配数据时的文案
  4. }
Object-
onchange左右数据穿梭时的回调Function详见穿梭时的回调

数据源格式解析

数据格式解析的回调函数,用于将任意数据格式解析成 transfer 组件规定的数据格式,以下是合法的数据格式如下:

 

合法的数据格式code

[
{"value": "1", "title": "李白", "disabled": "", "checked": ""}
,{"value": "2", "title": "杜甫", "disabled": "", "checked": ""}
,{"value": "3", "title": "贤心", "disabled": "", "checked": ""}
]

然而很多时候你返回的数据格式可能并不符合规范,比如:

 

不符合规范的数据格式code

[
{"id": "1", "name": "李白"}
,{"id": "2", "name": "杜甫"}
,{"id": "3", "name": "贤心"}
]

那么您需要将其解析成 transfer 组件所规定的数据格式:

 

codecode

transfer.render({
elem: '#text1'
,data: [
{"id": "1", "name": "李白"}
,{"id": "2", "name": "杜甫"}
,{"id": "3", "name": "贤心"}
]
,parseData: function(res){
return {
"value": res.id //数据值
,"title": res.name //数据标题
,"disabled": res.disabled //是否禁用
,"checked": res.checked //是否选中
}
}
});

左右穿梭的回调

当数据在左右穿梭时触发,回调返回当前被穿梭的数据

 

例子code

transfer.render({
elem: '#text'
,data: [] //数据源
,onchange: function(data, index){
console.log(data); //得到当前被穿梭的数据
console.log(index); //如果数据来自左边,index 为 0,否则为 1
}
});

基础方法

基础用法是组件关键组成部分,目前所开放的所有方法如下:

 

</>code

var transfer = layui.transfer;

transfer.set(options); //设定全局默认参数。options 即各项基础参数
transfer.getData(id); //获得右侧数据
transfer.reload(id, options); //重载实例

获得右侧数据

穿梭框的右侧数据通常被认为是选中数据,因此你需要得到它并提交到后台。

 

例子code

transfer.render({
elem: '#test'
,data: []
,id: 'demo1' //定义索引
});

//获得右侧数据
var getData = transfer.getData('demo1');

实例重载

重载一个已经创建的组件实例,被覆盖新的基础属性

 

例子code

transfer.render({
elem: '#test'
,data: []
,id: 'demo1' //定义索引
});

//可以重载所有基础参数
transfer.reload('demo1', {
title: ['新列表1', '新列表2']
});

 

十、树形组件文档 - layui.tree

在一段漫长的雪藏后,我们在 layui 2.5.0 的版本中重新创作了 tree,以便它能够更加适用于绝大多数业务场景,而风格依然遵循 layui 独有的极简和清爽。需要提醒的是,如果您的项目中仍然采用了 layui 2.5 版本之前的 tree,它将不被兼容,请尽快修改为以下新的调用方式。

模块加载名称:tree

快速使用

通过 tree.render() 方法指定一个元素,便可快速创建一个 tree 实例。

 

</>code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>树组件</title>
<link rel="stylesheet" href="../src/css/layui.css">
</head>
<body>
<div id="test1"></div>
<script src="../src/layui.js"></script>
<script>
layui.use('tree', function(){
var tree = layui.tree;

//渲染
var inst1 = tree.render({
elem: '#test1' //绑定元素
,data: [{
title: '江西' //一级菜单
,children: [{
title: '南昌' //二级菜单
,children: [{
title: '高新区' //三级菜单
//…… //以此类推,可无限层级
}]
}]
},{
title: '陕西' //一级菜单
,children: [{
title: '西安' //二级菜单
}]
}]
});
});
</script>
</body>
</html>

基础参数

目前 tree 组件提供以下基础参数,可根据需要进行相应的设置

参数选项说明类型示例值
elem指向容器选择器String/Object-
data数据源Array详见数据选项
id设定实例唯一索引,用于基础方法传参使用。String-
showCheckbox是否显示复选框Booleanfalse
edit是否开启节点的操作图标。默认 false。
  • 若为 true,则默认显示“改删”图标
  • 若为 数组,则可自由配置操作图标的显示状态和顺序,目前支持的操作图标有:addupdatedel,如:

    edit: ['add', 'update', 'del']
Boolean/Array['update', 'del']
accordion是否开启手风琴模式,默认 falseBooleanfalse
onlyIconControl是否仅允许节点左侧图标控制展开收缩。默认 false(即点击节点本身也可控制)。若为 true,则只能通过节点左侧图标来展开收缩Booleanfalse
isJump是否允许点击节点时弹出新窗口跳转。默认 false,若开启,需在节点数据中设定 link 参数(值为 url 格式)Booleanfalse
showLine是否开启连接线。默认 true,若设为 false,则节点左侧出现三角图标。Booleantrue
text自定义各类默认文本,目前支持以下设定:
 

</>code

  1. text: {
  2. defaultNodeName: '未命名' //节点默认名称
  3. ,none: '无数据' //数据为空时的提示文本
  4. }
Object-

数据源属性选项

我们将 data 参数称之为数据源,其内部支持设定以下选项

属性选项说明类型示例值
title节点标题String未命名
id节点唯一索引值,用于对指定节点进行各类操作String/Number任意唯一的字符或数字
field节点字段名String一般对应表字段名
children子节点。支持设定选项同父节点Array[{title: '子节点1', id: '111'}]
href点击节点弹出新窗口对应的 url。需开启 isJump 参数String任意 URL
spread节点是否初始展开,默认 falseBooleantrue
checked节点是否初始为选中状态(如果开启复选框的话),默认 falseBooleantrue
disabled节点是否为禁用状态。默认 falseBooleanfalse

节点被点击的回调

在节点被点击后触发,返回的参数如下:

 

例子code

tree.render({
elem: '#test1'
,click: function(obj){
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.state); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素

console.log(obj.data.children); //当前节点下是否有子节点
}
});

复选框被点击的回调

点击复选框时触发,返回的参数如下:

 

例子code

tree.render({
elem: '#test1'
,oncheck: function(obj){
console.log(obj.data); //得到当前点击的节点数据
console.log(obj.checked); //得到当前节点的展开状态:open、close、normal
console.log(obj.elem); //得到当前节点元素
}
});

操作节点的回调

通过 operate 实现函数,对节点进行增删改等操作时,返回操作类型及操作节点

 

例子code

tree.render({
elem: '#test1'
,operate: function(obj){
var type = obj.type; //得到操作类型:add、edit、del
var data = obj.data; //得到当前节点的数据
var elem = obj.elem; //得到当前节点元素

//Ajax 操作
var id = data.id; //得到节点索引
if(type === 'add'){ //增加节点
//返回 key 值
return 123;
} else if(type === 'update'){ //修改节点
console.log(elem.find('.layui-tree-txt').html()); //得到修改后的内容
} else if(type === 'del'){ //删除节点

};
}
});

返回选中的节点数据

很多时候 tree 可能不仅仅只是一个树菜单,它还用于各种权限控制等场景,这个时候你需要获得选中的节点。
语法:tree.getChecked(id)

 

例子code

tree.render({
elem: '#test'
,data: [] //数据源
,id: 'demoId' //定义索引
});

//获得选中的节点
var checkData = tree.getChecked('demoId');

设置节点勾选

除了通过 checked 参数对节点进行初始勾选之外,你还可以通过方法动态对节点执行勾选
语法: tree.setChecked(id, checkedId)
参数 checkedId:代表的是数据源中的节点 id

 

例子code

tree.render({
elem: '#test'
,data: [] //数据源
,id: 'demoId' //定义索引
});

//执行节点勾选
tree.setChecked('demoId', 1); //单个勾选 id 为 1 的节点
tree.setChecked('demoId', [2, 3]); //批量勾选 id 为 2、3 的节点

实例重载

重载一个已经创建的组件实例,被覆盖新的基础属性

 

例子code

tree.render({
elem: '#test'
,data: []
,id: 'demoId' //定义索引
});

//可以重载所有基础参数
tree.reload('demoId', {
//新的参数
});

十一、颜色选择器文档 - layui.colorpicker

在主题定制的应用场景中,自然离不开颜色的自定义。而你往往需要的是关于它的直观选择,于是 colorpicker 模块姗姗来迟,它支持 hex、rgb、rgba 三类色彩模式,在代码中简单的调用后,便可在你的网页系统中自由拖拽去选择你中意的颜色。
模块加载名称: colorpicker

注意:colorpicker 为 layui 2.4.0 新增模块,不支持 ie10 以下版本,其它高级浏览器均支持。

使用

colorpicker 是一款颜色选择器,如下是一个最基本的用法:

 

小例子code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>颜色选择器</title>
<link rel="stylesheet" href="../src/css/layui.css">
</head>
<body>
<div id="test1"></div>
<script src="../src/layui.js"></script>
<script>
layui.use('colorpicker', function(){
var colorpicker = layui.colorpicker;
//渲染
colorpicker.render({
elem: '#test1' //绑定元素
});
});
</script>
</body>
</html>

基础参数

colorpicker 组件目前支持以下参数

参数选项说明类型默认值
elem指向容器选择器string/object-
color默认颜色,不管你是使用 hex、rgb 还是 rgba 的格式输入,最终会以指定的格式显示。string-
format颜色显示/输入格式,可选值: hexrgb
若在 rgb 格式下开启了透明度,格式会自动变成 rgba。在没有输入颜色的前提下,组件会默认为 #000 也就是黑色。
stringhex(即 16 进制色值)
alpha是否开启透明度,若不开启,则不会显示透明框。开启了透明度选项时,当你的默认颜色为 hex 或 rgb 格式,组件会默认加上值为 1 的透明度。相同的,当你没有开启透明度,却以 rgba 格式设置默认颜色时,组件会默认没有透明度。
注意:该参数必须配合 rgba 颜色值使用
booleanfalse
predefine预定义颜色是否开启booleanfalse
colors预定义颜色,此参数需配合 predefine: true 使用。Array此处列举一部分:['#ff4500','#1e90ff','rgba(255, 69, 0, 0.68)','rgb(255, 120, 0)']
size下拉框大小,可以选择:lg、sm、xs。string-

预定义颜色

预定义颜色,可以被认为是提供的参考色,因此除了我们默认的预定义颜色之外,你还可以自己定义

 

小例子code

layui.use('colorpicker', function(){
var colorpicker = layui.colorpicker;、

colorpicker.render({
elem: '#test1'
,predefine: true
,colors: ['#F00','#0F0','#00F','rgb(255, 69, 0)','rgba(255, 69, 0, 0.5)']
});
});

颜色被改变的回调

回调名:change
当颜色在选择器中发生选择改变时,会进入 change 回调,你可以通过它来进行所需操作,下面的例子就是实时的输出当前选择器的颜色

 

小例子code

layui.use('colorpicker', function(){
var colorpicker = layui.colorpicker;

colorpicker.render({
elem: '#test1'
,change: function(color){
console.log(color)
}
});
});

颜色选择后的回调

回调名:done
点击颜色选择器的“确认”和“清除”按钮,均会触发 done 回调,回调返回当前选择的色值。

 

小例子code

layui.use('colorpicker', function(){
var colorpicker = layui.colorpicker;

colorpicker.render({
elem: '#test1'
,done: function(color){
console.log(color)
//譬如你可以在回调中把得到的 color 赋值给表单
}
});
});

十二、常用元素操作 - layui.element

页面中有许多元素需要自动去完成一些处理,譬如导航菜单的小滑块、Tab 的切换等操作,他们往往不需要去单独调用一个方法来开启一项功能,而页面上恰恰有太多这样的小交互,所以我们统一归类为 element 组件。
模块加载名称: element

使用

元素功能的开启只需要加载element模块即会自动完成,所以不用跟其它模块一样为某一个功能而调用一个方法。她只需要找到她支持的元素,如你的页面存在一个 Tab元素块,那么element模块会自动赋予她该有的功能。

 

HTMLcode

<div class="layui-tab" lay-filter="demo">
<ul class="layui-tab-title">
<li class="layui-this">网站设置</li>
<li>商品管理</li>
<li>订单管理</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">内容1</div>
<div class="layui-tab-item">内容2</div>
<div class="layui-tab-item">内容3</div>
</div>
</div>

前提是你要加载element模块

 

JavaScriptcode

layui.use('element', function(){
var element = layui.element;

//一些事件触发
element.on('tab(demo)', function(data){
console.log(data);
});
});

预设元素属性

我们通过自定义元素属性来作为元素的功能参数,他们一般配置在容器外层,如:

 

</>code

<div class="layui-tab" lay-allowClose="true" lay-filter="demo">…</div>
<span class="layui-breadcrumb" lay-separator="|"></span>

And So On

element 模块支持的元素如下表:

属性名可选值说明
lay-filter任意字符事件过滤器(公用属性),主要用于事件的精确匹配,跟选择器是比较类似的。
lay-allowClosetrue针对于Tab容器,是否允许选项卡关闭。默认不允许,即不用设置该属性
lay-separator任意分隔符针对于面包屑容器

基础方法

基础方法允许你在外部主动对元素发起一起操作,目前element模块提供的方法如下:

方法名描述
var element = layui.element;element模块的实例
返回的element变量为该实例的对象,携带一些用于元素操作的基础方法
element.on(filter, callback);用于元素的一些事件触发
element.tabAdd(filter, options);用于新增一个Tab选项
参数filter:tab元素的 lay-filter="value" 过滤器的值(value)
参数options:设定可选值的对象,目前支持的选项如下述示例:
 

</>code

  1. element.tabAdd('demo', {
  2. title: '选项卡的标题'
  3. ,content: '选项卡的内容' //支持传入html
  4. ,id: '选项卡标题的lay-id属性值'
  5. });
element.tabDelete(filter, layid);用于删除指定的Tab选项
参数filter:tab元素的 lay-filter="value" 过滤器的值(value)
参数layid:选项卡标题列表的 属性 lay-id 的值
 

示例code

  1. element.tabDelete('demo', 'xxx'); //删除 lay-id="xxx" 的这一项
element.tabChange(filter, layid);用于外部切换到指定的Tab项上,参数同上,如:
element.tabChange('demo', 'layid'); //切换到 lay-id="yyy" 的这一项
element.tab(options);用于绑定自定义 Tab 元素(即非 layui 自带的 tab 结构)。该方法为 layui 2.1.6 新增
参数options:设定可选值的对象,目前支持的选项如下述示例:
 

</>code

  1. //HTML
  2. <ul id="tabHeader">
  3. <li>标题1</li>
  4. <li>标题2</li>
  5. <li>标题3</li>
  6. </ul>
  7. <div id="tabBody">
  8. <div class="xxx">内容1</div>
  9. <div class="xxx">内容2</div>
  10. <div class="xxx">内容4</div>
  11. </div>
  12. //JavaScript
  13. element.tab({
  14. headerElem: '#tabHeader>li' //指定tab头元素项
  15. ,bodyElem: '#tabBody>.xxx' //指定tab主体元素项
  16. });
element.progress(filter, percent);用于动态改变进度条百分比:
element.progress('demo', '30%');

更新渲染

更新渲染

跟表单元素一样,很多时候你的页面元素可能是动态生成的,这时element的相关功能将不会对其有效,你必须手工执行 element.init(type, filter) 方法即可。注意:2.1.6 开始,可以用 element.render(type, filter); 方法替代

第一个参数:type,为表单的type类型,可选。默认对全部类型的表单进行一次更新。可局部刷新的type如下表:

参数(type)值描述
tab重新对tab选项卡进行初始化渲染
nav重新对导航进行渲染
breadcrumb重新对面包屑进行渲染
progress重新对进度条进行渲染
collapse重新对折叠面板进行渲染
 

例子code

element.init(); //更新全部 2.1.6 可用 element.render() 方法替代
element.render('nav'); //重新对导航进行渲染。注:layui 2.1.6 版本新增
//……

第二个参数:filter,为元素的 lay-filter="" 的值。你可以借助该参数,完成指定元素的局部更新。

 

</>code

  1. 【HTML】
    <div class="layui-nav" lay-filter="test1">
    …
    </div>
    
    <div class="layui-nav" lay-filter="test2">
    …
    </div>

  2. 【JavaScript】
    //比如当你对导航动态插入了二级菜单,这时你需要重新去对它进行渲染
    element.render('nav', 'test1'); //对 lay-filter="test1" 所在导航重新渲染。注:layui 2.1.6 版本新增
    //……

事件触发

语法:element.on('event(过滤器值)', callback);

element 模块在 layui 事件机制中注册了element 模块事件,所以当你使用 layui.onevent() 自定义模块事件时,请勿占用 element 名。目前 element 模块所支持的事件如下表:

event描述
tab触发 Tab 选项卡切换事件
tabDelete触发 Tab 选项卡删除事件
nav触发导航菜单的点击事件
collapse触发折叠面板展开或收缩事件

默认情况下,事件所触发的是全部的元素,但如果你只想触发某一个元素,使用事件过滤器即可。
如:<div class="layui-tab" lay-filter="test"></div>

 

</>code

element.on('tab(test)', function(data){
console.log(data);
});

触发选项卡切换

Tab选项卡点击切换时触发,回调函数返回一个object参数,携带两个成员:

 

</>code

element.on('tab(filter)', function(data){
console.log(this); //当前Tab标题所在的原始DOM元素
console.log(data.index); //得到当前Tab的所在下标
console.log(data.elem); //得到当前的Tab大容器
});

触发选项卡删除

Tab选项卡被删除时触发,回调函数返回一个object参数,携带两个成员:

 

</>code

element.on('tabDelete(filter)', function(data){
console.log(this); //当前Tab标题所在的原始DOM元素
console.log(data.index); //得到当前Tab的所在下标
console.log(data.elem); //得到当前的Tab大容器
});

注:该事件为 layui 2.1.6 新增

触发导航菜单的点击

当点击导航父级菜单和二级菜单时触发,回调函数返回所点击的菜单DOM对象:

 

</>code

element.on('nav(filter)', function(elem){
console.log(elem); //得到当前点击的DOM对象
});

触发折叠面板

当折叠面板点击展开或收缩时触发,回调函数返回一个object参数,携带三个成员:

 

</>code

element.on('collapse(filter)', function(data){
console.log(data.show); //得到当前面板的展开状态,true或者false
console.log(data.title); //得到当前点击面板的标题区域DOM对象
console.log(data.content); //得到当前点击面板的内容区域DOM对象
});

动态操作进度条

你肯定不仅仅是满足于进度条的初始化显示,通常情况下你需要动态改变它的进度值,element模块提供了这样的基础方法:element.progress(filter, percent);

 

例子code

<div class="layui-progress layui-progress-big" lay-filter="demo" lay-showPercent="true">
<div class="layui-progress-bar" lay-percent="0%"></div>
</div>

上述是一个已经设置了过滤器(lay-filter="demo")的进度条

现在你只需要在某个事件或者语句中执行方法:element.progress('demo', '50%');

即可改变进度

如果你需要进度条更直观的例子,建议浏览:进度条演示页面

十三、滑块文档 - layui.slider

作为一个拖拽式的交互性组件,滑块往往能给产品带来更好的操作体验。layui 深以为然,slider 模块包含了你能想到的大部分功能,尽管它可以作为一个独立的个体,但很多时候它往往会出现 form 元素中,想象一下吧。
模块加载名称: slider

注意:slider 为 layui 2.4.0 新增模块

使用

通过对 slider 模块的使用,你可以在页面构建出可拖动的滑动元素,如下是一个最基本的用法:

 

小例子code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>滑块</title>
<link rel="stylesheet" href="../src/css/layui.css">
</head>
<body>
<div id="slideTest1"></div>
<script src="../src/layui.js"></script>
<script>
layui.use('slider', function(){
var slider = layui.slider;

//渲染
slider.render({
elem: '#slideTest1' //绑定元素
});
});
</script>
</body>
</html>

基础参数

slider 组件支持以下参数

参数选项说明类型默认值
elem指向容器选择器string/object-
type滑块类型,可选值有:default(水平滑块)、vertical(垂直滑块)stringdefault
min滑动条最小值,正整数,默认为 0number0
max滑动条最大值number100
range是否开启滑块的范围拖拽,若设为 true,则滑块将出现两个可拖拽的环booleanfalse
value滑块初始值,默认为数字,若开启了滑块为范围拖拽(即 range: true),则需赋值数组,异表示开始和结尾的区间,如:value: [30, 60]number/Array0
step拖动的步长number1
showstep是否显示间断点booleanfalse
tips是否显示文字提示booleantrue
input是否显示输入框(注意:若 range 参数为 true 则强制无效)
点击输入框的上下按钮,以及输入任意数字后回车或失去焦点,均可动态改变滑块
booleanfalse
height滑动条高度,需配合 type:"vertical" 参数使用number200
disabled是否将滑块禁用拖拽booleanfalse
theme主题颜色,以便用在不同的主题风格下string#009688

自定义提示文本

当鼠标放在圆点和滑块拖拽时均会触发提示层。其默认显示的文本是它的对应数值,你也可以自定义提示内容:

 

例子code

slider.render({
elem: '#slideTest1'
,setTips: function(value){ //自定义提示文本
return value + '%';
}
});

数值改变的回调

在滑块数值被改变时触发。该回调非常重要,可动态获得滑块当前的数值。你可以将得到的数值,赋值给隐藏域,或者进行一些其它操作。

 

小例子code

//当滑块为普通模式,回调返回的 value 是一个数值
slider.render({
elem: '#slideTest1'
,change: function(value){
console.log(value) //动态获取滑块数值
//do something
}
});

//当滑块为范围模式,回调返回的 value 是一个数组,包含开始和结尾
slider.render({
elem: '#slideTest1'
,range: true
,change: function(value){
console.log(value[0]) //得到开始值
console.log(value[1]) //得到结尾值
//do something
}
});

实例方法

执行 slider 实例时,会返回一个当前实例的对象,里面包含针对当前实例的方法和属性。
语法:var ins1 = slider.render(options);

 

实例方法和属性code

var ins1 = slider.render(options); //获得实例对象

ins1.config //获得当前实例的配置项
ins1.setValue(nums); //动态给滑块赋值

动态改变滑块数值

你可以通过外部方法动态改变滑块数值,如:

 

</>code

var ins1 = slider.render({
elem: '#test1'
//…
});

//改变指定滑块实例的数值
ins1.setValue(20)

//若滑块开启了范围(range: true)
ins1.setValue(20, 0) //设置开始值
ins1.setValue(60, 1) //设置结尾值

十四、评分组件文档 - layui.rate

rate 评分组件在电商和 O2O 平台尤为常见,一般用于对商家进行服务满意度评价。外形依然小巧自然,功能依旧灵活实用。其中评分对应的自定义内容功能,可让它有更多的发挥空间。该组件为 2.3.0 版本新增
模块加载名称: rate

使用

rate 组件可以用来进行展示或评价,你只需要通过更改参数设定来开启你想要的功能,如下是一个最基本的例子:

 

layui.rate小例子code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>评分组件</title>
<link rel="stylesheet" href="../src/css/layui.css">
</head>
<body>
<div id="test1"></div>
<script src="../src/layui.js"></script>
<script>
layui.use('rate', function(){
var rate = layui.rate;

//渲染
var ins1 = rate.render({
elem: '#test1' //绑定元素
});
});
</script>
</body>
</html>

这真的就是个小例子,所以下文对组件的参数进行了说明,请仔细阅读奥

基础参数

目前 rate 组件提供了以下基础参数,你可根据实际场景进行相应的设置

参数选项说明类型默认值
elem指向容器选择器string/object-
length评分组件中具体星星的个数。个数当然是整数啦,残缺的星星很可怜的,所以设置了小数点的组件我们会默认向下取整number5
value评分的初始值number0
theme主题颜色。我们默认的组件颜色是#FFB800,你可以根据自身喜好来更改组件的颜色,以适用不同场景string#FFB800
half设定组件是否可以选择半星booleanfalse
text是否显示评分对应的内容booleanfalse
readonly是否只读,即只用于展示而不可点booleanfalse

分数设置

如若你设置分数,我们会根据你是否开启半星功能,来做一个具体的规范:

关闭半星功能:

  • 小数值大于 0.5 :分数向上取整,如 3.6 分,则系统自动更改为 4 分
  • 小数值小于等于 0.5 :分数向下取整,如 3.2 分,则系统自动更改为 3 分
  • 如果在关闭半星功能的情况下开启了文本,你会发现你的分数也相应的变成了整数

开启半星功能:

  • 不论你的小数值是 0.1 还是 0.9,都统一规划为 0.5,在文本开启的情况下,你可以看见你的分数并没有发生变化

自定义文本的回调

通过 setText 函数,在组件初次渲染和点击后时产生回调。我们默认文本以星级显示,你可以根据自己设定的文字来替换我们的默认文本,如 “讨厌” “喜欢” 。若用户选择分数而没有设定对应文字的情况下,系统会使用我们的默认文本

 

例子code

rate.render({
elem: '#test1'
,setText: function(value){
var arrs = {
'1': '极差'
,'2': '差'
,'3': '中等'
,'4': '好'
};
this.span.text(arrs[value] || ( value + "星"));
}
});

当你点击 3 星时,文本内容是中等,点击 5 星时,由于没有设定对应文字,所以文本会显示 5 星

点击产生的回调

通过 choose 实现函数,在组件被点击后触发,回调分数,用户可根据分数来设置效果,比如出现弹出层

 

例子code

rate.render({
elem: '#test1'
,choose: function(value){
if(value > 4) alert( '么么哒' )
}
});

那么当你点击 5 星或更高星级时,页面就会弹出“么么哒”啦,你可根据相应需求在 choose 里完善你的代码

十五、通用轮播组件文档 - layui.carousel

carousel 是 layui 2.0 版本中新增的全新模块,主要适用于跑马灯/轮播等交互场景。它并非单纯地为焦点图而生,准确地说,它可以满足任何类型内容的轮播式切换操作,更可以胜任 FullPage (全屏上下轮播)的需求,简洁而不失强劲,灵活而优雅。

模块加载名称:carousel

快速使用

如下是几个常用的轮播示例,其中背景色是为了区分条目单独加的,在layui框架中并不会包含。条目区域可以放上文字列表、图片等任意内容

条目3



 

对应的代码code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>carousel模块快速使用</title>
<link rel="stylesheet" href="/static/build/layui.css" media="all">
</head>
<body>

<div class="layui-carousel" id="test1">
<div carousel-item>
<div>条目1</div>
<div>条目2</div>
<div>条目3</div>
<div>条目4</div>
<div>条目5</div>
</div>
</div>
<!-- 条目中可以是任意内容,如:<img src=""> -->

<script src="/static/build/layui.js"></script>
<script>
layui.use('carousel', function(){
var carousel = layui.carousel;
//建造实例
carousel.render({
elem: '#test1'
,width: '100%' //设置容器宽度
,arrow: 'always' //始终显示箭头
//,anim: 'updown' //切换动画方式
});
});
</script>
</body>
</html>

在HTML结构中,只需要简单地注意这两项:
1) 外层元素的 class="layui-carousel" 用来标识为一个轮播容器
2) 内层元素的属性 carousel-item 用来标识条目

而 id 则用于carousel模块建造实例的元素指向,剩下的工作,就是按照你的实际需求,给方法设置不同的基础参数了。

基础参数选项

通过核心方法:carousel.render(options) 来对轮播设置基础参数,也可以通过方法:carousel.set(options) 来设定全局基础参数.

可选项说明类型默认值
elem指向容器选择器,如:elem: '#id'。也可以是DOM对象string/object
width设定轮播容器宽度,支持像素和百分比string'600px'
height设定轮播容器高度,支持像素和百分比string'280px'
full是否全屏轮播booleanfalse
anim轮播切换动画方式,可选值为:
  • default(左右切换)
  • updown(上下切换)
  • fade(渐隐渐显切换)
string'default'
autoplay是否自动切换booleantrue
interval自动切换的时间间隔,单位:ms(毫秒),不能低于800number3000
index初始开始的条目索引number0
arrow切换箭头默认显示状态,可选值为:
  • hover(悬停显示)
  • always(始终显示)
  • none(始终不显示)
string'hover'
indicator指示器位置,可选值为:
  • inside(容器内部)
  • outside(容器外部)
  • none(不显示)

注意:如果设定了 anim:'updown',该参数将无效
string'inside'
trigger指示器的触发事件string'click'

切换事件

轮播的每一次切换时触发,回调函数返回一个object参数,携带的成员如下:

 

</>code

var carousel = layui.carousel;

//触发轮播切换事件
carousel.on('change(test1)', function(obj){ //test1来源于对应HTML容器的 lay-filter="test1" 属性值
console.log(obj.index); //当前条目的索引
console.log(obj.prevIndex); //上一个条目的索引
console.log(obj.item); //当前条目的元素对象
});

重置轮播

事实上,在执行 carousel.render(options) 方法时,有返回一个当前实例的对象。该对象包含了用于操作当前轮播的一些属性和方法。

 

</>code

var ins = carousel.render(options);

//重置轮播
ins.reload(options);

十六、富文本编辑器文档 - layui.layedit

国内外有许多优秀、强大的HTML编辑器,但普遍都有一个共性:异常地臃肿(少则几千行,多则上万行代码)、UI陈旧,并且基本都好几年没更新了。而现在,随着Layui的发布,我们有必要重新为富文本做一些新的定义。LayEdit仍旧遵循极简的设计风格,无论是UI上,还是接口使用上,都尽可能地避免一些繁杂的功能和配置。如果你正苦苦寻找一款轻量的Web富文本编辑器,那么LayEdit会是你不错的选择。

模块加载名称:layedit

使用

跟那些过往的编辑器一样,你需要放置一个标签(一般为textarea文本域)作为编辑器的目标元素,然后调用 layedit.build('id') 即可,如下所示:

 

</>code

<textarea id="demo" style="display: none;"></textarea>
<script>
layui.use('layedit', function(){
var layedit = layui.layedit;
layedit.build('demo'); //建立编辑器
});
</script>

然后你会看到一个如下模样(部分工具Bar未配置出来),它跟Layui的所有存在体一样,兼容IE6/7以外的全部浏览器。

基础方法

LayEdit提供了相当精简的方法,如下:

方法名描述
var index = layedit.build(id, options)用于建立编辑器的核心方法
index:即该方法返回的索引
参数 id: 实例元素(一般为textarea)的id值
参数 options:编辑器的可配置项,下文会做进一步介绍
layedit.set(options)设置编辑器的全局属性
即上述build方法的options
layedit.getContent(index)获得编辑器的内容
参数 index: 即执行layedit.build返回的值
layedit.getText(index)获得编辑器的纯文本内容
参数 index: 同上
layedit.sync(index)用于同步编辑器内容到textarea(一般用于异步提交)
参数 index: 同上
layedit.getSelection(index)获取编辑器选中的文本
参数 index: 同上

编辑器基本设置

在建立编辑器的方法 layedit.build(id, options) 的第二个参数(options)中,允许我们对编辑器进行一些设置,如:

 

</>code

layedit.build('id', {
height: 180 //设置编辑器高度
});

options可提供支持的参数如下表

属性类型描述
toolArray重新定制编辑器工具栏,如: tool: ['link', 'unlink', 'face']
hideToolArray不显示编辑器工具栏,一般用于隐藏默认配置的工具bar
heightNumber设定编辑器的初始高度
uploadImageObject设定图片上传接口,如:uploadImage: {url: '/upload/', type: 'post'}

自定义工具Bar

通过下述方式可自定义编辑器的工具Bar

 

</>code

layedit.build('id', {
tool: ['left', 'center', 'right', '|', 'face']
});

目前layedit可选的Bar有(顺序可以自由排列):

 

</>code

tool: [
'strong' //加粗
,'italic' //斜体
,'underline' //下划线
,'del' //删除线
,'|' //分割线
,'left' //左对齐
,'center' //居中对齐
,'right' //右对齐
,'link' //超链接
,'unlink' //清除链接
,'face' //表情
,'image' //插入图片
,'help' //帮助
]

插入图片接口

LayEdit提供了向编辑器插入图片的支持,前提是配置了 uploadImage,如:

 

</>code

layedit.set({
uploadImage: {
url: '' //接口url
,type: '' //默认post
}
});
//注意:layedit.set 一定要放在 build 前面,否则配置全局接口将无效。
layedit.build('demo'); //建立编辑器

也就是说LayEdit并不提供服务端的图片接受,但你需要在图片上传成功后对LayEdit返回如下格式的JSON信息:

 

</>code

{
"code": 0 //0表示成功,其它失败
,"msg": "" //提示信息 //一般上传失败后返回
,"data": {
"src": "图片路径"
,"title": "图片名称" //可选
}
}

十七、流加载文档 - layui.flow

该模块包含 信息流加载图片懒加载两大核心支持,无论是对服务端、还是前端体验,都有非常大的性能帮助。你可能已经在太多的地方看到她们的身影了,但不妨现在开始,体验一下Layui更为简单和高效的Flow吧。

模块加载名称:flow

使用

flow模块包含两个核心方法,如下所示:

 

</>code

layui.use('flow', function(){
var flow = layui.flow;
//信息流
flow.load(options);

//图片懒加载
flow.lazyimg(options);
});

下面将对她们进行详细介绍。

信息流

信息流即异步逐页渲染列表元素,这是你页面已经存在的一段列表,你页面初始时只显示了6个

 

HTMLcode

<ul id="demo">
<li>1</li>
<li>2</li>
……
<li>6</li>
</ul>

你想通过加载更多来显示余下列表,那么你只需要执行方法:flow.load(options) 即可

 

JavaScriptcode

layui.use('flow', function(){
var $ = layui.jquery; //不用额外加载jQuery,flow模块本身是有依赖jQuery的,直接用即可。
var flow = layui.flow;
flow.load({
elem: '#demo' //指定列表容器
,done: function(page, next){ //到达临界点(默认滚动触发),触发下一页
var lis = [];
//以jQuery的Ajax请求为例,请求下一页数据(注意:page是从2开始返回)
$.get('/api/list?page='+page, function(res){
//假设你的列表返回在data集合中
layui.each(res.data, function(index, item){
lis.push('<li>'+ item.title +'</li>');
});

//执行下一页渲染,第二参数为:满足“加载更多”的条件,即后面仍有分页
//pages为Ajax返回的总页数,只有当前页小于总页数的情况下,才会继续出现加载更多
next(lis.join(''), page < res.pages);
});
}
});
});

上述是一个比较简单的例子,以下是信息流完整的参数支撑(即options对象),它们将有助于你更灵活地应对各种场景

参数类型描述
elemstring指定列表容器的选择器
scrollElemstring滚动条所在元素选择器,默认document。如果你不是通过窗口滚动来触发流加载,而是页面中的某一个容器的滚动条,那么通过该参数指定即可。
isAutoboolean是否自动加载。默认true。如果设为false,点会在列表底部生成一个“加载更多”的button,则只能点击它才会加载下一页数据。
endstring用于显示末页内容,可传入任意HTML字符。默认为:没有更多了
isLazyimgboolean是否开启图片懒加载。默认false。如果设为true,则只会对在可视区域的图片进行按需加载。但与此同时,在拼接列表字符的时候,你不能给列表中的img元素赋值src,必须要用lay-src取代,如:
 

JavaScript片段code

  1. layui.each(res.data, function(index, item){
  2. lis.push('<li><img lay-src="'+ item.src +'"></li>');
  3. });
mbnumber与底部的临界距离,默认50。即当滚动条与底部产生该距离时,触发加载。注意:只有在isAuto为true时有效。
额,等等。。mb=margin-bottom,可不是骂人的呀。
donefunction到达临界点触发加载的回调。信息流最重要的一个存在。携带两个参数:
 

JavaScript片段code

  1. done: function(page, next){
  2. //请注意:layui 1.0.5 之前的版本是从第2页开始返回,也就是说你的第一页数据并非done来触发加载
  3. (为之前这个愚蠢的设计表示抱歉)
  4. //从 layui 1.0.5 的版本开始,page是从1开始返回,初始时即会执行一次done回调。
  5. //console.log(page) //获得当前页
  6. //执行下一页渲染,第二参数为:满足“加载更多”的条件,即后面仍有分页
  7. //只有当前页小于总页数的情况下,才会继续出现加载更多
  8. next('列表HTML片段', page < res.pages);
  9. }

图片懒加载

应该说比当前市面上任何一个懒加载的实现都更为强劲和轻量,她用不足80行代码巧妙地提供了一个始终加载当前屏图片的高性能方案(无论上滑还是下滑)。对你的网站因为图片可能带来的压力,可做出很好的应对。

语法:flow.lazyimg(options)

 

</>code

layui.use('flow', function(){
var flow = layui.flow;
//当你执行这样一个方法时,即对页面中的全部带有 lay-src 的 img 元素开启了懒加载(当然你也可以指定相关 img)
flow.lazyimg();
});

如上所述,它只会针对以下 img 元素有效:

 

HTMLcode

<img src="占位图地址" lay-src="预加载图地址">
<img src="" src="bbb.jpg">
<img src="" lay-src="ccc.jpg">
占位图功能为 layui 2.6.6 开始新增。 这本应在 1.0 就该支持,但由于重心在其他组件,导致姗姗来迟。

如你所见,图片懒加载的使用极其简单,其参数(options 对象)可支持的 key 如下表所示:

参数类型描述
elemstring指定开启懒加载的img元素选择器,如 elem: '.demo img' 或 elem: 'img.load'
scrollElemstring滚动条所在元素选择器,默认document。如果你不是通过窗口滚动来触发流加载,而是页面中的某一个容器的滚动条,那么通过该参数指定即可。

 

十八、工具集文档 - layui.util

我们将一些工具性元素放入  util 模块中,以供选择性使用。其内部由多个小工具组件组成,他们也许不是必须的,但很多时候却能为你的页面提供良好的辅助作用。
模块加载名称: util

固定块

语法:util.fixbar(options)
其中参数 options 是一个对象,可支持的key如下表:

参数类型描述
bar1Boolean/String默认false。如果值为true,则显示第一个bar,带有一个默认图标。
如果值为图标字符,则显示第一个bar,并覆盖默认图标
bar2Boolean/String默认false。如果值为true,则显示第二个bar,带有一个默认图标。
如果值为图标字符,则显示第二个bar,并覆盖默认图标
bgcolorString自定义区块背景色
showHeightNumber用于控制出现TOP按钮的滚动条高度临界值。默认:200
cssObject你可以通过重置bar的位置,比如 css: {right: 100, bottom: 100}
clickFunction点击bar的回调,函数返回一个type参数,用于区分bar类型。
支持的类型有:bar1、bar2、top
 

例子code

layui.use('util', function(){
var util = layui.util;

//执行
util.fixbar({
bar1: true
,click: function(type){
console.log(type);
if(type === 'bar1'){
alert('点击了bar1')
}
}
});
});

倒计时

这是一个精致的封装,它并不负责视图的呈现,而仅返回倒计时数值,这意味着你可以将它应用在任何倒计时相关的业务中。

语法:util.countdown(endTime, serverTime, callback)

参数说明
endTime结束时间戳或Date对象,如:4073558400000,或:new Date(2099,1,1).
serverTime当前服务器时间戳或Date对象
callback回调函数。如果倒计时尚在运行,则每一秒都会执行一次。并且返回三个参数: date(包含天/时/分/秒的对象)、 serverTime(当前服务器时间戳或Date对象), timer(计时器返回的ID值,用于clearTimeout)
 

例子code

<div id="test"></div>

<script>
layui.use('util', function(){
var util = layui.util;

//示例
var endTime = new Date(2099,1,1).getTime() //假设为结束日期
,serverTime = new Date().getTime(); //假设为当前服务器时间,这里采用的是本地时间,实际使用一般是取服务端的

util.countdown(endTime, serverTime, function(date, serverTime, timer){
var str = date[0] + '天' + date[1] + '时' + date[2] + '分' + date[3] + '秒';
layui.$('#test').html('距离2099年1月1日还有:'+ str);
});
});
</script>

其它方法

方法说明
util.timeAgo(time, onlyDate)某个时间在当前时间的多久前。
参数 time:即为某个时间的时间戳或日期对象
参数 onlyDate:是否在超过30天后,只返回日期字符,而不返回时分秒

如果在3分钟以内,返回:刚刚
如果在30天以内,返回:若干分钟前若干小时前若干天前,如:5分钟前
如果在30天以上,返回:日期字符,如:2017-01-01
util.toDateString(time, format)转化时间戳或日期对象为日期格式字符
参数 time:可以是日期对象,也可以是毫秒数
参数 format:日期字符格式(默认:yyyy-MM-dd HH:mm:ss),可随意定义,如:yyyy年MM月dd日
util.digit(num, length)数字前置补零
参数 num:原始数字
参数 length:数字长度,如果原始数字长度小于 length,则前面补零,如:util.digit(7, 3) //007
util.escape(str)转义 xss 字符
参数 str:任意字符
util.event(attr, obj, eventType)用于更好地批量处理事件。
参数 attr:绑定需要监听事件的元素属性
参数 obj:事件回调链
参数 eventType:事件类型(默认 click)

示例:
 

</>code

  1. HTML:
  2. <button class="layui-btn" lay-active="e1">事件1</button>
  3. <button class="layui-btn" lay-active="e2">事件2</button>
  4. <button class="layui-btn" lay-active="e3">事件3</button>
  5. JavaScript:
  6. <script>
  7. layui.use('util', function(){
  8. var util = layui.util;
  9. //处理属性 为 lay-active 的所有元素事件
  10. util.event('lay-active', {
  11. e1: function(othis){
  12. alert('触发了事件1');
  13. }
  14. ,e2: function(othis){
  15. alert('触发了事件2');
  16. }
  17. ,e3: function(othis){
  18. alert('触发了事件3');
  19. }
  20. });
  21. });
  22. </script>

十九、代码高亮文档 - layui.code

该组件暂时只对你的  pre 元素进行一个修饰,从而保证你展现的代码更具可读性。目前它没有对不同的语言进行颜色高亮(后续逐步强化),但这丝毫不会影响它对你带来的便捷。

模块加载名称:code

使用

code模块的使用非常简单,请直接看代码,假设你在页面有这样一段pre标签:

 

htmlcode

<pre class="layui-code">
//代码区域
var a = 'hello layui';
</pre>

那么你只需要经过下面的方式:

 

JavaScriptcode

layui.use('code', function(){ //加载code模块
layui.code(); //引用code方法
});

就可以将那段pre区块显示成你现在看到的这个样子:

 

</>code

//代码区域
var a = 'hello layui';

基础参数

方法:layui.code(options)
它接受一个对象参数options,支持以下key的设定

参数类型描述
elemstring指定元素的选择器
titlestring设定标题
heightstring设置最大高度
encodeboolean是否转义html标签,默认false
skinstring风格选择(值见下文)
aboutboolean是否剔除右上关于

特别提示:除了上述方式的设置,我们还允许你直接在pre标签上设置属性来替代,如:

 

</>code

<pre class="layui-code" lay-title="" lay-height="" lay-skin="" lay-encode="">
这样有木有觉得更方便些
</pre>

下面将针对每一个参数做进一步讲解。

指定元素

code模块会去自动查找class为layui-code的类,如果你初始给的不是该类,仅仅只是一个pre标签,那么需要通过elem设置选择器来指向元素:

 

JavaScriptcode

layui.code({
elem: 'pre' //默认值为.layui-code
});

设置标题

即左上角显示的文本,默认值为code

 

JavaScriptcode

layui.code({
title: 'JavaScript'
});

或者直接在pre标签上设置属性<pre lay-title="JavaScript"></pre>

设置最大高度

你可以设置以下key来控制修饰器的最大高度。如果内容低于该高度,则会自适应内容高度;如果内容超过了该高度,则会自动出现滚动条。

 

JavaScriptcode

layui.code({
height: '100px' //请注意必须加px。如果该key不设定,则会自适应高度,且不会出现滚动条。
});




Hi,我是充数的 ^_^

或者直接在pre标签上设置属性<pre lay-height="100px"></pre>

转义html标签

事实上很多时候你都需要在pre标签中展现html标签,而不希望它被浏览器解析。那么code模块允许你这么做,只需要开启encode即可,如:

 

JavaScriptcode

layui.code({
encode: true //是否转义html标签。默认不开启
});

开启了encode后的效果如下:

 

显示htmlcode

<ul>
<li>HTML将不会被解析</li>
<li>有木有感觉非常方便</li>
</ul>
<script>
!function(){
var a = 123;
}();
</script>

或者直接在pre标签上设置属性<pre lay-encode="true"></pre>

风格选择

你肯定不会满足于code的某一种显示风格,而skin参数则允许你设定许多种显示风格,我们目前内置了两种,分别为默认和notepad

 

JavaScriptcode

layui.code({
title: 'NotePad++的风格'
,skin: 'notepad' //如果要默认风格,不用设定该key。
});

上述的设定后,你会看到下面的样子

 

NotePad++的风格code

  1. i'm code.
  2. i'm code too.

或者直接在pre标签上设置属性<pre lay-skin="notepad"></pre>

  • 1
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:书香水墨 设计师:CSDN官方博客 返回首页
评论

打赏作者

£轻描~淡写°

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值