目录
一、开始使用 - 入门指南
UNPKG 引入示例code
HTML
二、底层方法
三、页面元素规范与说明
四、模块规范
五、常见问题
JScode
JavaScriptcode
六、各大版本更新日志
2.6.x
v2.6.8 2021-05-30
v2.6.7 2021-05-18
v2.6.6 2021-05-08
v2.6.5 2021-04-22
v2.6.3/4 2021-04-05 / 2021-04-06
v2.6.2 2021-04-02
v2.6.1 2021-03-31
v2.6.0 2021-03-31
[新增] dropdown 通用下拉菜单组件 #文档 #示例
2.5.x
v2.5.7 2020-11-27
v2.5.6 2020-01-15
v2.5.5 2019-09-10
v2.5.4 2019-06-06
v2.5.2 / v2.5.3 2019-06-04
v2.5.1 2019-06-03
v2.5.0 2019-05-31
[新增] tree 组件
[新增] transfer 穿梭组件
[加强] table 组件
[加强] form 组件
[完善] upload 组件
[完善] 其他
2.4.x
v2.4.5 2018-11-01
v2.4.4 2018-10-29
v2.4.3 2018-09-03
v2.4.2 2018-08-30
v2.4.1 2018-08-29
v2.4.0 2018-08-28
[加强] table 组件
[新增] colorpicker 颜色选择器组件
[新增] slider 滑块组件
[完善] form 组件
其它
2.3.0
rate 评分
laypage 通用分页
laydate 日期与时间
form 表单
upload 文件上传
flow 流加载
其它改动
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
table 改进
form 改进
其它改进
注意事项
2.1.7
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
功能新增
完善与优化
Bug Fixes
2.1.0
功能新增
完善与优化
Bug Fixes
2.0.2
layDate 日期时间选择器
Table 表格
其它
2.0.1
layDate 日期时间选择器
Table 表格
其它
2.0.0
Table 表格
Carousel 轮播
Layout 布局
layDate 日期时间选择器
Upload 上传
layPage 分页
Form 表单集合
Layer 弹层
Element 页面元素
Util 工具集
底层方法
其它更改
Bug fixes
1.x 升 2.0 特别注意事项
1.0.1 到 1.0.9
1.0.0
layui(谐音:类 UI) 是一套开源的 Web UI 解决方案,采用自身经典的模块化规范,并遵循原生 HTML/CSS/JS 的开发方式,极易上手,拿来即用。其风格简约轻盈,而组件优雅丰盈,从源代码到使用方法的每一处细节都经过精心雕琢,非常适合网页界面的快速开发。layui 区别于那些基于 MVVM 底层的前端框架,却并非逆道而行,而是信奉返璞归真之道。准确地说,它更多是面向后端开发者,你无需涉足前端各种工具,只需面对浏览器本身,让一切你所需要的元素与交互,从这里信手拈来。 ——前端网页框架
兼容性和面向场景
layui 兼容人类正在使用的全部浏览器(IE6/7除外),可作为 Web 界面速成开发方案。
获得 layui
1. 官网首页下载
你可以在我们的 官网首页 下载到 layui 的最新版,它经过了自动化构建,更适合用于生产环境。目录结构如下:
├─css //css目录
│ │─modules //模块 css 目录(一般如果模块相对较大,我们会单独提取,如下:)
│ │ ├─laydate
│ │ └─layer
│ └─layui.css //核心样式文件
├─font //字体图标目录
└─layui.js //核心库
2. Git 仓库下载
你也可以通过 GitHub 或 码云 得到 layui 的完整开发包,以便于你进行二次开发,或者 Fork layui 为我们贡献方案
GitHub 码云
3. npm 下载
npm i layui
4. 第三方 CDN 方式引入:
UNPKG CDNJS
UNPKG 和 CDNJS 均为第三方开源免费的 CDN,通过 NPM/GitHub 实时同步。另外还有 LayuiCDN。
快速上手
如果你将 layui 下载到了本地,那么可将其完整地放置到你的项目目录(或静态资源服务器),这是一个基本的入门页面:
开始使用 layui
经典,因返璞归真
layui 定义为「经典模块化」,并非是自吹她自身有多优秀,而是有意避开当下 JS 社区的主流方案,试图以尽可能简单的方式去诠释高效!她的所谓经典,是在于对返璞归真的执念,她以当前浏览器普通认可的方式去组织模块!我们认为,这恰是符合当下国内绝大多数程序员从旧时代过渡到未来新标准的绝佳指引。所以 layui 本身也并不是完全遵循于 AMD 时代,准确地说,她试图建立自己的模式:
//layui 模块的定义(新 js 文件)
layui.define([mods], function(exports){
//……
exports('mod', api);
});
//layui 模块的使用
layui.use(['mod1', 'mod2'], function(args){
var mod = layui.mod1;
//……
});
没错,她具备早前 AMD 的影子,又并非受限于 CommonJS 的那些条条框框,layui 认为这种轻量的组织方式,比WebPack更符合绝大多数场景。所以她坚持采用经典模块化,也正是能让人避开工具的复杂配置,回归简单,安静高效地编织原生态的 HTML/CSS/JS。
但是 layui 又并非是 RequireJS 那样的模块加载器,而是一款 UI 解决方案,与 BootStrap 的不同又在于:layui 糅合了自身对经典模块化的理解。这使得你可以在 layui 组织的框架之内,以更具可维护性的代码、去更好的编织丰富的用户界面。
建立模块入口
您可以遵循 layui 的模块规范建立一个入口文件,并通过 layui.use() 方式来加载该入口文件,如下所示:
上述的 index 即为你 /res/js/modules/ 目录下的 index.js,它的内容应该如下:
/**
index.js 项目 JS 主入口
以依赖 layui 的 layer 和 form 模块为例
**/
layui.define(['layer', 'form'], function(exports){
var layer = layui.layer
,form = layui.form;
layer.msg('Hello World');
exports('index', {}); //注意,这里是模块输出的核心,模块名必须和 use 时的模块名一致
});
从 layui 2.6 开始,如果你引入的是构建后的 layui.js
,里面即包含了 layui 所有的内置模块,无需再指定内置模块。如:
/**
index.js 项目 JS 主入口
**/
layui.define(function(){ // 需确保您的 layui.js 是引入的构建后的版本(即官网下载或 git 平台的发行版)
//直接可得到各种内置模块
var layer = layui.layer
,form = layui.form
,table = layui.table;
//…
layer.msg('Hello World');
exports('index', {}); //注意,这里是模块输出的核心,模块名必须和 use 时的模块名一致
});
管理扩展模块
除了使用 layui 的内置模块,必不可少也需要加载扩展模块(可以简单理解为符合 layui 模块规范的 JS 文件)。我们假设你的项目中存放了很多个扩展模块,如下所举:
//mod1.js
layui.define('layer', function(exports){
//…
exports(mod1, {});
});
//mod2.js,假设依赖 mod1 和 form
layui.define(['mod1', 'form'], function(exports){
//…
exports(mod2, {});
});
//mod3.js
//…
//main.js 主入口模块
layui.define('mod2', function(exports){
//…
exports('main', {});
});
在经过了一定的模块依赖关系后,同样可以合并为一个文件来加载。我们可以借助 Gulp 将上述的 mod1、mod2、mod3、main
等扩展模块构建合并到一个模块文件中:main.js
,此时你只需要加载它即可:
可以看到,这样我们最多只需要加载两个 JS 文件:layui.js、main.js
。这将大幅度减少静态资源的请求。
本篇主要介绍基础库所发挥的作用,其中过滤了大部分在外部不常用的方法,侧重罗列了基础框架支撑。
全局配置
方法:layui.config(options)
你可以在使用模块之前,全局化配置一些参数,尽管大部分时候它不是必须的。所以我们目前提供的全局配置项非常少,这也是为了减少一些不必要的工作,尽可能让使用变得更简单。目前支持的全局配置项如下:
layui.config({
dir: '/res/layui/' //layui.js 所在目录(如果是 script 单独引入 layui.js,无需设定该参数)一般可无视
,version: false //一般用于更新模块缓存,默认不开启。设为 true 即让浏览器不缓存。也可以设为一个固定的值,如:201610
,debug: false //用于开启调试模式,默认 false,如果设为 true,则JS模块的节点会保留在页面
,base: '' //设定扩展的 layui 模块的所在目录,一般用于外部模块扩展
});
如果你对 layui.js 本身进行了动态加载等其他特殊场景,那么上述layui.config
所设定的dir
参数会因此失效,它会在部分组件的依赖文件(css)加载后才执行,此时你可以在动态加载 layui.js
之前预先定义一个我们约定好的全局对象:
提示:以上 dir 参数的目录设定仅针对特殊场景,如是采用 script 标签正常引入 layui 的,可以无视该 dir 参数。
定义模块
方法:layui.define([mods], callback)
通过该方法可在新的 JS 文件中定义一个 layui 模块。参数 mods 是可选的,用于声明该模块所依赖的模块。callback 即为模块加载完毕的回调函数,它返回一个 exports 参数,用于输出该模块的接口。
/** demo.js **/
layui.define(function(exports){
//do something
exports('demo', {
msg: 'Hello Demo'
});
});
跟 RequireJS 最大不同的地方在于接口输出,exports 是一个函数,它接受两个参数,第1个参数为模块名,第2个参数为模块接口。
当你声明了上述的一个模块后,你就可以在外部使用了,demo 就会注册到 layui 对象下,即可通过 var demo = layui.demo
去得到该模块接口。你也可以在定义一个模块的时候,声明该模块所需的依赖,如:
/** demo.js **/
layui.define(['layer', 'laypage', 'mod1'], function(exports){ //此处 mod1 为你的任意扩展模块
//do something
exports('demo', {
msg: 'Hello Demo'
});
});
上述的 layer、laypage
都是 layui 的内置模块。
加载模块
方法:layui.use([mods], callback)
//引用指定模块
layui.use(['layer', 'laydate'], function(){
var layer = layui.layer
,laydate = layui.laydate;
//do something
});
//引用所有模块(layui 2.6 开始支持)
layui.use(function(){
var layer = layui.layer
,laydate = layui.laydate
,table = layui.table;
//…
//do something
});
你还可以通过回调函数得到模块对象,如
layui.use(['layer', 'laydate', 'table'], function(layer, laydate, table){
//使用 layer
layer.msg('test');
//使用 laydate
laydate.render({});
//使用 table
table.render({})
});
动态加载 CSS
方法:layui.link(href)
href 即为 css 路径。注意:该方法并非是你使用 layui 所必须的,它一般只是用于动态加载你的外部 CSS 文件。
本地存储
本地存储是对 localStorage 和 sessionStorage 的友好封装,可更方便地管理本地数据。
- localStorage 持久化存储:layui.data(table, settings),数据会永久存在,除非物理删除。
- sessionStorage 会话性存储:layui.sessionData(table, settings),页面关闭后即失效。注:layui 2.2.5 新增
上述两个方法的使用方式是完全一样的。其中参数 table 为表名,settings是一个对象,用于设置 key、value。下面以 layui.data 方法为例:
//【增】:向 test 表插入一个 nickname 字段,如果该表不存在,则自动建立。
layui.data('test', {
key: 'nickname'
,value: '贤心'
});
//【删】:删除 test 表的 nickname 字段
layui.data('test', {
key: 'nickname'
,remove: true
});
layui.data('test', null); //删除test表
//【改】:同【增】,会覆盖已经存储的数据
//【查】:向 test 表读取全部的数据
var localTest = layui.data('test');
console.log(localTest.nickname); //获得“贤心”
获取浏览器信息
方法:layui.device(key),参数 key 是可选的
由于 layui 的一些功能进行了兼容性处理和响应式支持,因此该方法同样发挥了至关重要的作用。其返回的信息如下:
var device = layui.device();
//device 即可根据不同的设备返回下述不同的信息
{
os: "windows" //当前浏览器所在的底层操作系统,如:Windows、Linux、Mac 等
,ie: false //当前浏览器是否为 ie6-11 的版本,如果不是 ie 浏览器,则为 false
,weixin: false //当前浏览器是否为微信 App 环境
,android: false //当前浏览器是否为安卓系统环境
,ios: false //当前浏览器是否为 IOS 系统环境
,mobile: false //当前浏览器是否为移动设备环境(v2.5.7 新增)
}
有时你的 App 可能会对 userAgent 插入一段特定的标识,譬如:
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 myapp/1.8.6 Safari/537.36
你要验证当前的 WebView 是否在你的 App 环境,即可通过上述的myapp(即为 Native 给 Webview 插入的标识,可以随意定义)来判断。
var device = layui.device('myapp');
if(device.myapp){
alert('在我的App环境');
}
其它底层方法
除上述介绍的方法外,layui 内部还提供了许多底层引擎,他们同样是整个 layui 框架的有力支撑,在日常应用中通常也会用到:
方法/属性 | 描述 |
---|---|
layui.cache | 静态属性。获得一些配置及临时的缓存信息 |
layui.extend(options) | 拓展一个模块别名,如:layui.extend({test: '/res/js/test'}) |
layui.each(obj, fn) | 对象(Array、Object、DOM 对象等)遍历,可用于取代 for 语句 |
layui._typeof(operand) | 获取详细数据类型(基本数据类型和各类常见引用类型)如:
|
layui._isArray(obj) | 对象是否为泛数组结构。如 Array、NodeList、jQuery 对象等等。
|
layui.getStyle(node, name) | 获得一个原始 DOM 节点的 style 属性值,如:layui.getStyle(document.body, 'font-size') |
layui.img(url, callback, error) | 图片预加载 |
layui.sort(obj, key, desc) | 将数组中的对象按某个成员重新对该数组排序,如:layui.sort([{a: 3},{a: 1},{a: 5}], 'a') |
layui.router() | 获得 location.hash 路由结构,一般在单页面应用中发挥作用。 |
layui.url(href) | 用于将一段 URL 链接中的 pathname、search、hash 属性值进行对象化处理 参数: href 可选。若不传,则自动读取当前页面的 url(即:location.href) |
layui.hint() | 向控制台打印一些异常信息,目前只返回了 error 方法:layui.hint().error('出错啦'); |
layui.stope(e) | 阻止事件冒泡 |
layui.onevent(modName, events, callback) | 增加自定义模块事件。有兴趣的同学可以阅读 layui.js 源码以及 form 模块 |
layui.event(modName, events, params) | 执行自定义模块事件,搭配 onevent 使用 |
layui.off(events, modName) | 用于移除模块相关事件的监听(v2.5.7 新增) 如: |
layui.factory(modName) | 用于获取模块对应的 define 回调函数 |
第三方工具
layui 部分模块依赖 jQuery(比如 layer),但是你并不用去额外加载 jQuery。layui 已经将 jQuery 最稳定的一个版本改为 layui 的内部模块,当你去使用 layer 之类的模块时,它会首先判断你的页面是否已经引入了 jQuery,如果没有,则加载内部的 jQuery 模块,如果有,则不会加载。
另外,我们的图标取材于阿里巴巴矢量图标库(iconfont),构建工具采用 Gulp 。除此之外,不依赖于任何第三方工具。
layui 提倡返璞归真,遵循于原生态的元素书写规则,所以通常而言,你仍然是在写基本的 HTML 和 CSS 代码,不同的是,在 HTML 结构上及 CSS 定义上需要小小遵循一定的规范。
CSS内置公共基础类
类名(class) | 说明 |
---|---|
布局 / 容器 | |
layui-main | 用于设置一个宽度为 1140px 的水平居中块(无响应式) |
layui-inline | 用于将标签设为内联块状元素 |
layui-box | 用于排除一些UI框架(如Bootstrap)强制将全部元素设为box-sizing: border-box所引发的尺寸偏差 |
layui-clear | 用于消除浮动(一般不怎么常用,因为layui几乎没用到浮动) |
layui-btn-container | 用于定义按钮的父容器。(layui 2.2.5 新增) |
layui-btn-fluid | 用于定义流体按钮。即宽度最大化适应。(layui 2.2.5 新增) |
辅助 | |
layui-icon | 用于图标 |
layui-elip | 用于单行文本溢出省略 |
layui-unselect | 用于屏蔽选中 |
layui-disabled | 用于设置元素不可点击状态 |
layui-circle | 用于设置元素为圆形 |
layui-show | 用于显示块状元素 |
layui-hide | 用于隐藏元素 |
文本 | |
layui-text | 定义一段文本区域(如文章),该区域内的特殊标签(如a、li、em等)将会进行相应处理 |
layui-word-aux | 灰色标注性文字,左右会有间隔 |
背景色 | |
layui-bg-red | 用于设置元素赤色背景 |
layui-bg-orange | 用于设置元素橙色背景 |
layui-bg-green | 用于设置元素墨绿色背景(主色调) |
layui-bg-cyan | 用于设置元素藏青色背景 |
layui-bg-blue | 用于设置元素蓝色背景 |
layui-bg-black | 用于设置元素经典黑色背景 |
layui-bg-gray | 用于设置元素经典灰色背景 |
字体大小及颜色 | |
>code
|
CSS命名规范
class命名前缀:layui,连接符:-,如:class="layui-form"
命名格式一般分为两种:一:layui-模块名-状态或类型,二:layui-状态或类型。因为有些类并非是某个模块所特有,他们通常会是一些公共类。如:一(定义按钮的原始风格):class="layui-btn layui-btn-primary"、二(定义内联块状元素):class="layui-inline"
大致记住这些简单的规则,会让你在填充HTML的时候显得更加得心应手。另外,如果你是开发Layui拓展(模块),你最好也要遵循于类似的规则,并且请勿占用Layui已经命名好的类,假设你是在帮Layui开发一个markdown编辑器,你的css书写规则应该如下:
.layui-markdown{border: 1px solid #e2e2e2;}
.layui-markdown-tools{}
.layui-markdown-text{}
HTML规范:结构
Layui在解析HTML元素时,必须充分确保其结构是被支持的。以Tab选项卡为例:
- 标题一
- 标题二
- 标题三
内容1
内容2
内容3
你如果改变了结构,极有可能会导致Tab功能失效。所以在嵌套HTML的时候,你应该细读各个元素模块的相关文档(如果你不是拿来主义)
HTML规范:常用公共属性
很多时候,元素的基本交互行为,都是由模块自动开启。但不同的区域可能需要触发不同的动作,这就需要你设定我们所支持的自定义属性来作为区分。如下面的 lay-submit、lay-filter即为公共属性(即以 lay- 作为前缀的自定义属性):
目前我们的公共属性如下所示(即普遍运用于所有元素上的属性)
属性 | 描述 |
---|---|
lay-skin=" " | 定义相同元素的不同风格,如checkbox的开关风格 |
lay-filter=" " | 事件过滤器。你可能会在很多地方看到他,他一般是用于监听特定的自定义事件。你可以把它看作是一个ID选择器 |
lay-submit | 定义一个触发表单提交的button,不用填写值 |
layui 定义了一套更轻量的模块规范。并且这种方式在经过了大量的实践后,成为 layui 最核心的模块加载引擎。
预先加载模块
layui 通过 use 方法加载模块。当你的 JS 需要用到 layui 模块的时候,且避免到处写 layui.use() 的麻烦。你应该在最外层如此定义:
layui.use(['form', 'upload'], function(){ //如果只加载一个模块,可以不填数组。如:layui.use('form')
var form = layui.form //获取form模块
,upload = layui.upload; //获取upload模块
//监听提交按钮
form.on('submit(test)', function(data){
console.log(data);
});
//实例化一个上传控件
upload({
url: '上传接口url'
,success: function(data){
console.log(data);
}
})
});
模块命名空间
layui 的模块对象会绑定在 layui 对象下,内部由 layui.define() 方法来完成。每个模块都有一个特定命名,且无法被占用。所以你无需担心模块的空间被污染,除非你主动 delete layui['模块名']。调用模块可通过 layui.use() 来实现,再通过 layui 对象获得模块对象。如:
layui.use(['layer', 'laypage', 'laydate'], function(){
var layer = layui.layer //获得 layer 模块
,laypage = layui.laypage //获得 laypage 模块
,laydate = layui.laydate; //获得 laydate 模块
//使用模块
});
我们推荐你将所有的业务代码都写在一个大的 use 回调中,而不是将模块接口暴露给全局,比如下面的方式我们是极不推荐的:
//强烈不推荐下面的做法
var laypage, laydate;
layui.use(['laypage', 'laydate'], function(){
laypage = layui.laypage;
laydate = layui.laydate;
});
你之所以想使用上面的错误方式,是想其它地方使用不在执行一次 layui.use?但这种理解本身是存在问题的。因为如果一旦你的业务代码是在模块加载完毕之前执行,你的全局对象将获取不到模块接口,因此这样用不仅不符合规范,还存在报错风险。建议在你的 js 文件中,在最外层写一个 layui.use 来加载所依赖的模块,并将业务代码写在回调中,这样还可以确保 html 文档加载完毕再执行回调代码。
扩展一个 layui 模块
layui 官方提供的模块有时可能还无法满足你,或者你试图按照layer的模块规范来扩展一个模块。那么你有必要认识layui.define()方法,相信你在文档左侧的“底层方法”中已有所阅读。下面就让我们一起扩展一个 layui 模块吧:
第一步:确认模块名,假设为:mymod,然后新建一个mymod.js 文件放入项目任意目录下(注意:不用放入layui目录)
第二步:编写 mymod.js 如下:
/**
扩展一个 mymod 模块
**/
layui.define(function(exports){ //提示:模块也可以依赖其它模块,如:layui.define('mod1', callback);
var obj = {
hello: function(str){
alert('Hello '+ (str||'mymod'));
}
};
//输出 mymod 接口
exports('mymod', obj);
});
第三步:设定扩展模块所在的目录,然后就可以在别的JS文件中使用了
//config的设置是全局的
layui.config({
base: '/res/js/' //假设这是你存放拓展模块的根目录
}).extend({ //设定模块别名
mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名
,mod1: 'admin/mod1' //相对于上述 base 目录的子目录
});
//你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)
layui.extend({
mod2: '{/}http://cdn.xxx.com/lib/mod2' // {/}的意思即代表采用自有路径,即不跟随 base 路径
})
//使用拓展模块
layui.use(['mymod', 'mod1'], function(){
var mymod = layui.mymod
,mod1 = layui.mod1
,mod2 = layui.mod2;
mymod.hello('World!'); //弹出 Hello World!
});
本篇将主要讲解使用过程中普遍遇到的“问题”,并非是 BUG,通常是需要我们自己去注意的一些点。(持续补充)
哪里有 layui 未压缩源代码?
之所以在下载包里没有提供未压缩的源代码,是为了方便直接用于生产环境。layui 源代码可通过以下平台获取:
GitHub Gitee
应该如何加载模块?
layui.use(['layer', 'form', 'element'], function(){
var layer = layui.layer
,form = layui.form
,element = layui.element
//……
//你的代码都应该写在这里面
});
为什么表单不显示?
当你使用表单时,layui 会对 select、checkbox、radio 等原始元素隐藏,从而进行美化修饰处理。但如果您的表单元素是动态添加的,那么在组件初始加载的时候是无法读取到的,这是你只需执行一个视图渲染的实例即可。#详见说明
layui.use('form', function(){
var form = layui.form; //只有执行了这一步,部分表单元素才会自动修饰成功
//……
//如果你的 HTML 是动态生成的,自动渲染就会失效
//因此你需要在相应的地方,执行下述方法来进行渲染
form.render();
});
同理的还有 element 模块
遇到各种问题怎么办?
求助 Gitee 开发者社区: Issues
该版本重要提示:
- [调整] 将所有内置模块构建为一个文件,这意味着 当你引入的是从官网下载(或者开源平台下载的 dist 目录)的 layui.js,则不必再按需异步加载内置模块,直接即可使用 layui 所有组件库。该调整对模块化的写法不受影响。
但需注意以下几点:
- 1) 如果之前引入了 layui.all.js 的,现在必须改成 layui.js
- 2) 如果元素存在动态插入,那么您需要执行元素所对应组件的 render() 方法,如 form.render()
- 3) 引入 layui.js 的