Layuimini
Layuimini是什么
Layuimini是Layui的升级版,它是专业做后台页面的框架,而且是适合PC端和移动端。以下地址可以在PC端显示,也可以在手机上显示,只不过会做自适应。
英才汇硕UOLab管理系统
在以前,手机端访问的页面需要专门开发,现在用Layuimi就可以一套系统两个平台都可以访问,可以大大提升开发效率,节省公司的开发成本。如果没有接触过Layui,需要先学习这个。
如何获得Layuimini
百度Layuimini得到以下地址:
Layuimini
通过以下地址可以下载Layuimini的v2版,不过需要先有Gitee或Github账号
Layuimini-Gitee
下载后,用WebStorm打开这个工程。 WebStorm适合做前端的开发
Layuimini界面
在浏览器中看到的情形是:
可以看到这个页面分了几个区域,这是典型的后台管理页面的样式,我们可以在这个基础之上修改为自己的系统。
所要修改的是菜单的内容,以及菜单对应的页面,在页面上加上后台的地址,就构成了管理系统。
开始自己的修改
菜单的修改
现在我想加入自己的菜单,如何操作?在页面上查看菜单的内容:
我们以"菜单管理"为例,其他的菜单同理,在WebStrom搜索"菜单管理"四个字
用ctrl+shift+f打开搜索窗口,如果快捷键没有被占用的话,不过好多人的这个快捷键可能会和输入法发生冲突,关闭输入法的这个快捷键。
在搜索窗口输入"菜单管理"看到以上内容,发现是init.json文件是管理菜单的,如果不确定是这个文件,可以在搜索结果中查看其他文件以便确认,这些操作需要一些经验和直觉,这些能力需要慢慢培养。
找到init.json文件把"菜单管理"改为"用户管理"
如图所示,这个菜单链接的页面也相应改为了自己的页面userManager.html,这个页面可以随后创建一个,看看修改后的菜单样子。
增加页面
我们尝试增加一个用户管理页面userManager.html,可以在项目中找一个页面复制然后修改成想要的内容。
表格示例,这个页面是非常典型的后面管理页面,因为页面中有搜索区域,有表格展示数据,有增加、修改、删除的功能,表格中行内的删除是删除单和记录,表格上方的删除按钮可以批量删除多条记录,同时表格中的复选框要选中这些记录。我们通过上面提到的搜索办法找到这个页面对应的文件,复制然后重命名为userManager.html。
我的习惯是开发一个模块,一般是CRUD,增删改查的功能,这些功能以管理页面为主要页面,管理页面一般为xxxManager.html,在管理页面需要按照需要文档定下来查询区域按哪些信息查询,表格中需要展示哪些信息,对于信息比较多的模块,可以显示那些重要信息的字段,在行记录上做双击事件,或在行中给名称或编号代表当前记录的字段上增加链接跳转功能,用以打开详情页面,显示所有信息。管理页面上的功能和后台代码的简单对应关系:
页面功能 | 代码 |
---|---|
增加 | 链接userAdd.html |
修改 | 链接userModify.html |
行内删除 | 模板中行内删除事件 |
批量删除 | 模板中批量删除事件 |
以上代码可以在模板页面中找到相应的代码段,后面围绕着用户管理模块来分析这个模块下的几个文件的代码:useAdd.html,userModify.html,userDetail.html,userManager.html
userManager.html
html部分
...
<link rel="stylesheet" href="../lib/layui-v2.5.5/css/layui.css" media="all">
<link rel="stylesheet" href="../css/public.css" media="all">
...
<script src="../lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
以上代码中可以看到页面的效果是来自于layui.css、public.css、layui.js的支撑。
我们是在原有代码基础上进行修改的,原则上不改变既有代码风格的结构,只改变显示的文字内容和相应的变量及方法的命名等,页面上多余的元素可以删除,不够的可以仿照增加一些。
<form class="layui-form layui-form-pane" action="">
这行代码中的class是决定了页面显示的效果,具体详细的知识请到Layui网站查看
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">姓名</label>
<div class="layui-input-inline">
<input type="text" name="realName" placeholder="请输入姓名" autocomplete="off" class="layui-input">
</div>
</div>
...
</div>
<div class="layui-form-item">
这行代码是页面一行
<div class="layui-inline">
这行代码是行内
class="layui-form-item"独立的一行
class="layui-inline"不换行,直到一行占满后自动折到下一行
以下是查询区域内的代码:
<fieldset class="table-search-fieldset">
<legend>搜索信息</legend>
<div style="margin: 10px 10px 10px 10px">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">姓名</label>
<div class="layui-input-inline">
<input type="text" name="realName" placeholder="请输入姓名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">院系</label>
<div class="layui-input-inline">
<select >
<option value="">-请选择-</option>
<option value="1">计算机科学与技术学院</option>
<option value="2">电子信息工程学院</option>
<option value="3">机械电子工程学院</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">专业</label>
<div class="layui-input-inline">
<select >
<option value="">-请选择-</option>
<option value="1">计算机科学与技术</option>
<option value="2">软件工程</option>
<option value="3">网络工程</option>
</select>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">班级</label>
<div class="layui-input-inline">
<input type="text" name="classname" placeholder="请输入班级" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">年级</label>
<div class="layui-input-inline">
<input id="year" type="text" name="grade" placeholder="请选择入学年份" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button type="button" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button>
</div>
</div>
</form>
</div>
</fieldset>
此为部分代码,分析和讲解过程中的代码是局部的代码,随后会有完整代码供下载。
<div class="layui-inline">
<button type="button" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button>
</div>
从接触Layui或Layuimini开始,我们发现页面元素中有很多的class属性,这些都是Layui特有的样式,这些样式能保证我们看到的系统有Layui的外观。
这里的按钮有着白色的外观,带一个查询的图标。
以下是表格部分的代码:
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-normal layui-btn-sm" lay-event="add"> 添加用户 </button>
<button class="layui-btn layui-btn-danger layui-btn-sm " lay-event="delete"> 批量删除 </button>
</div>
</script>
<table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>
<!--自定义的列模板-->
<script type="text/html" id="statusTableBar">
<input type="checkbox" name="status" value="{{d.userid}}" checked lay-skin="switch" lay-text="启用|禁用"
lay-event="open" lay-filter="modifystatus" {{ d.status == '1'? 'checked' : '' }}/>
</script>
<script type="text/html" id="currentTableBar">
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="detail">查看详情</a>
<a class="layui-btn layui-btn-xs data-count-edit" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
</script>
以下是表格部分的一段代码,表格上面的工具栏部分
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-normal layui-btn-sm" lay-event="add"> 添加用户 </button>
<button class="layui-btn layui-btn-danger layui-btn-sm " lay-event="delete"> 批量删除 </button>
</div>
</script>
通过指定样式不同,按钮的外观不同lay-event="add"是将来在脚本中判断是哪个按钮触发的事件。
<table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>
这个是表格元素,id可以让脚本定位此元素,lay-filter是Layui用来定位和判断元素的依据,id适用于DOM和jQuery,lay-filter适用于Layui。
<!--自定义的列模板-->
<script type="text/html" id="statusTableBar">
<input type="checkbox" name="status" value="{{d.userid}}" checked lay-skin="switch" lay-text="启用|禁用"
lay-event="open" lay-filter="modifystatus" {{ d.status == '1'? 'checked' : '' }}/>
</script>
在Layui或其它一些前端产品中对于页面的一些元素一般会用模板来完成,如上面的代码,它是用来指定表格中用户状态一列的外观。模板其实一段内嵌的JS代码,但是这段JS代码中又会嵌套一些HTML元素,如上面的checkbox。
<script type="text/html" id="currentTableBar">
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="detail">查看详情</a>
<a class="layui-btn layui-btn-xs data-count-edit" lay-event="edit">修改</a>
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
</script>
这一段代码是关于表格中右边“操作“列中的内容
JS部分
<script>
layui.use(['form', 'table'], function () {
var $ = layui.jquery,
form = layui.form,
table = layui.table;
table.render({
elem: '#currentTableId',
url: '../api/user.json',
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', {
title: '提示',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
cols: [[
{type: "checkbox", width: 50},
{field: 'id', width: 80, title: 'ID', sort: true},
{field: 'realname', width: 80, title: '姓名'},
{field: 'deptname', width: 180, title: '院系'},
{field: 'majorname', width:160, title: '专业'},
{field: 'classname', title: '班级', width: 100},
{field: 'grade', width: 70, title: '年级', sort: true},
{field: 'telephone', width: 120, title: '手机号码'},
{
field : 'status',
width: 90,
title : '用户状态',
templet : '#statusTableBar',
unresize : true,
align: "center"
},
{title: '操作', minWidth: 130, toolbar: '#currentTableBar', align: "center"}
]],
limits: [10, 15, 20, 25, 50, 100],
limit: 15,
page: true,
skin: 'line'
});
// 监听搜索操作
form.on('submit(data-search-btn)', function (data) {
var result = JSON.stringify(data.field);
layer.alert(result, {
title: '最终的搜索信息'
});
//执行搜索重载
table.reload('currentTableId', {
page: {
curr: 1
}
, where: {
searchParams: result
}
}, 'data');
return false;
});
form.on('switch(modifystatus)', function(obj){
console.log(obj);
var param = obj.value;
});
/**
* toolbar监听事件
*/
table.on('toolbar(currentTableFilter)', function (obj) {
if (obj.event === 'add') { // 监听添加操作
var index = layer.open({
title: '添加用户',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['100%', '100%'],
content: 'addUser.html',
});
$(window).on("resize", function () {
layer.full(index);
});
} else if (obj.event === 'delete') { // 监听删除操作
var checkStatus = table.checkStatus('currentTableId')
, data = checkStatus.data;
layer.alert(JSON.stringify(data));
}
});
//监听表格复选框选择
table.on('checkbox(currentTableFilter)', function (obj) {
console.log(obj)
});
table.on('tool(currentTableFilter)', function (obj) {
var data = obj.data;
if(obj.event === 'detail'){
//layer.alert("查看详情");
var index = layer.open({
title: '查看详情',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['100%', '100%'],
content: 'userDetail.html',
});
$(window).on("resize", function () {
layer.full(index);
});
return false;
} else if (obj.event === 'edit') {
var index = layer.open({
title: '编辑用户',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['100%', '100%'],
content: 'editUser.html',
});
$(window).on("resize", function () {
layer.full(index);
});
return false;
} else if (obj.event === 'delete') {
layer.confirm('真的删除行么', function (index) {
obj.del();
layer.close(index);
});
}
});
});
// 年选择器(选择入学年份)
layui.use('laydate', function(){
var laydate = layui.laydate;
var initYear;
laydate.render({
elem: '#year',
type: 'year',
/* ready和change函数是为了实现选择年份时不用点确定直接关闭 */
ready: function(date){ // 控件在打开时触发,回调返回一个参数:初始的日期时间对象
initYear = date.year;
},
change: function(value, date, endDate){ // 年月日时间被切换时都会触发。回调返回三个参数,分别代表:生成的值、日期时间对象、结束的日期时间对象
var selectYear = date.year;
var differ = selectYear-initYear;
if (differ != 15 && differ != -15) {
if($(".layui-laydate").length){
$("#year").val(value);
$(".layui-laydate").remove();
}
}
initYear = selectYear;
}
});
});
</script>
以上代码量比较大,下面分别就其中的一些代码进行分析
layui.use(['form', 'table'], function () {
var $ = layui.jquery,
form = layui.form,
table = layui.table;
这里的use是引用Layui的两个模块,form和table,可以看到多个模块用中括号括起来,成为一个数组。
用var定义了三个变量,$、form、table,分别用到了Layui的三个模块,jquery比较特殊不用引入就可以直接使用。
table.render({
elem: '#currentTableId',
url: '../api/user.json',
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', {
title: '提示',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
cols: [[
{type: "checkbox", width: 50},
{field: 'id', width: 80, title: 'ID', sort: true},
{field: 'realname', width: 80, title: '姓名'},
{field: 'deptname', width: 180, title: '院系'},
{field: 'majorname', width:160, title: '专业'},
{field: 'classname', title: '班级', width: 100},
{field: 'grade', width: 70, title: '年级', sort: true},
{field: 'telephone', width: 120, title: '手机号码'},
{
field : 'status',
width: 90,
title : '用户状态',
templet : '#statusTableBar',
unresize : true,
align: "center"
},
{title: '操作', minWidth: 130, toolbar: '#currentTableBar', align: "center"}
]],
limits: [10, 15, 20, 25, 50, 100],
limit: 15,
page: true,
skin: 'line'
});
用table变量初始化表格,指定表格外观,功能,列,数据等信息
table.render是渲染表格render是table对象的一个方法,这个方法传入了一个参数,参数事体用{}括起来,所以它是一个JSON对象,不过这个JSON对象比较大。
属性 | 功能 |
---|---|
elem | 被渲染的对象 |
url | 表格数据源 |
toolbar | 表格顶部工具栏 |
defaultToolBar | 表格顶部右边的工具图标 |
cols | 表格的列 |
field | 字段名 |
title | 列标题 |
templet | 列的模板形式 |
field.toolbar | 工具列 |
limits | 分页信息每页可以选择的条数 |
limit | 每页条数 |
page | 是否带分页条 |
// 监听搜索操作
form.on('submit(data-search-btn)', function (data) {
var result = JSON.stringify(data.field);
layer.alert(result, {
title: '最终的搜索信息'
});
//执行搜索重载
table.reload('currentTableId', {
page: {
curr: 1
}
, where: {
searchParams: result
}
}, 'data');
return false;
});
对搜索按钮的监听,Layui和JS不一样的地方是,不需要在按钮上显示指定事件名方法,而是通过一些监听脚本来监听按钮上一些事件的发生,此处是对submit按钮的监听,并且data-search-btn是特定监听查询按钮。
layer.alert(result, {
title: '最终的搜索信息'
});
一个弹出框,result是内容,title是标题
//执行搜索重载
table.reload('currentTableId', {
page: {
curr: 1
}
, where: {
searchParams: result
}
}, 'data');
查询按钮会让表格重新加载数据,currentTableId是表格的lay-filter,{}部分是刷新表格时的查询条件
form.on('switch(modifystatus)', function(obj){
console.log(obj);
var param = obj.value;
});
表格中用户状态改变时作的处理
/**
* toolbar监听事件
*/
table.on('toolbar(currentTableFilter)', function (obj) {
if (obj.event === 'add') { // 监听添加操作
var index = layer.open({
title: '添加用户',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['100%', '100%'],
content: 'addUser.html',
});
$(window).on("resize", function () {
layer.full(index);
});
} else if (obj.event === 'delete') { // 监听删除操作
var checkStatus = table.checkStatus('currentTableId')
, data = checkStatus.data;
layer.alert(JSON.stringify(data));
}
});
表格上边工具栏的处理
table.on('tool(currentTableFilter)', function (obj) {
var data = obj.data;
if(obj.event === 'detail'){
//layer.alert("查看详情");
var index = layer.open({
title: '查看详情',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['100%', '100%'],
content: 'userDetail.html',
});
$(window).on("resize", function () {
layer.full(index);
});
return false;
} else if (obj.event === 'edit') {
var index = layer.open({
title: '编辑用户',
type: 2,
shade: 0.2,
maxmin:true,
shadeClose: true,
area: ['100%', '100%'],
content: 'editUser.html',
});
$(window).on("resize", function () {
layer.full(index);
});
return false;
} else if (obj.event === 'delete') {
layer.confirm('真的删除行么', function (index) {
obj.del();
layer.close(index);
});
}
});
表格中”操作“列的按钮处理
layer.open会打开一个新的页面
content: 'editUser.html’是指定的页面名称,因为页面是以页签的形式出现,title: ‘编辑用户’,是页签的标题
// 年选择器(选择入学年份)
layui.use('laydate', function(){
var laydate = layui.laydate;
var initYear;
laydate.render({
elem: '#year',
type: 'year',
/* ready和change函数是为了实现选择年份时不用点确定直接关闭 */
ready: function(date){ // 控件在打开时触发,回调返回一个参数:初始的日期时间对象
initYear = date.year;
},
change: function(value, date, endDate){ // 年月日时间被切换时都会触发。回调返回三个参数,分别代表:生成的值、日期时间对象、结束的日期时间对象
var selectYear = date.year;
var differ = selectYear-initYear;
if (differ != 15 && differ != -15) {
if($(".layui-laydate").length){
$("#year").val(value);
$(".layui-laydate").remove();
}
}
initYear = selectYear;
}
});
});
关于页面中年份的日期处理
- 增加了支持甘特图的mermaid语法1 功能;
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个 完美
的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
22=4
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown 将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎