一、layui介绍
1.是什么
layui是一个基于Web的前端UI框架,它专注于提供简洁、易用的界面元素和交互效果。它采用了模块化的设计,允许开发者根据需要选择性地引入其组件,从而提高开发效率和网站性能。layui的特点包括简单易用、扩展性强、兼容性好、文档丰富等,因此在许多Web开发项目中都被广泛使用。
2.谁开发的
由中国人开发(作者贤心),16年出厂的框架,其主要提供了很多好看、方便的样式,并且基本拿来即用,和Bootstrap有些相似,但该框架有个极大的好处就是定义了很多前后端交互的样式接口,如分页表格,只需在前端配置好接口,后端则按照定义好的接口规则返回数据,即可完成页面的展示,极大减少了后端人员的开发成本。
3.特点
- 简单易用: layui提供了简洁明了的界面元素和交互效果,使开发者能够快速构建美观的用户界面。
- 模块化设计: layui的模块化设计使得开发者可以根据项目需求选择性地引入需要的组件,减少了不必要的资源加载,提高了网站的性能。
- 扩展性强: layui提供丰富的组件和插件,同时也支持自定义扩展,开发者可以根据自己的需求进行定制和扩展。
- 兼容性好: layui兼容大多数主流浏览器,保证了在不同平台上的稳定运行。
- 文档丰富: layui拥有详细的官方文档和示例,提供了丰富的使用教程和API说明,方便开发者学习和使用。
- 生态丰富: layui拥有庞大的生态系统,有许多基于layui的插件和扩展可供选择,满足不同项目的需求。
1.layui、easyui与bootstrap的对比
1.设计风格:
- layui:layui的设计风格简洁、扁平化,注重用户体验和响应式布局。
- EasyUI:EasyUI的设计风格相对传统,注重功能的全面性和可定制性。
- Bootstrap:Bootstrap的设计风格现代、简洁,注重响应式布局和移动设备适配。
2.功能和组件:
- layui:layui提供丰富的常用UI组件、表单元素、弹窗、导航等功能模块,易于上手和扩展。
- EasyUI:EasyUI提供了大量的可定制的UI组件和表单元素,功能全面,适合构建复杂的企业级应用程序。
- Bootstrap:Bootstrap提供了用于快速构建响应式网站和Web应用所需的各种组件,包括网格系统、导航、按钮、表单等。
3.构建方式和兼容性:
- layui:layui采用模块化的构建方式,具有良好的兼容性,并且可以按需引入,减少资源加载。
- EasyUI:EasyUI采用jQuery插件的形式,依赖jQuery库,因此对jQuery的兼容性较好。
- Bootstrap:Bootstrap使用HTML、CSS和JavaScript构建,也可以按需引入,同时对各种浏览器的兼容性较好。
4.文档和社区支持:
- layui:layui拥有详细的官方文档和示例,社区活跃度较高,有许多插件和扩展可供选择。
- EasyUI:EasyUI的官方文档较为全面,并有大量的示例和教程可供参考,社区支持相对较好。
- Bootstrap:Bootstrap拥有丰富的官方文档、示例和模板,社区支持非常活跃,有大量的资源和插件可用。
选择适合的UI框架取决于项目需求、个人喜好和开发经验,layui适用于快速构建简洁的界面和Web应用,EasyUI适用于构建复杂的企业级应用,Bootstrap适用于构建现代、响应式的网站和Web应用。
2. layui和bootstrap对比(这两个都属于UI渲染框架)
1.layui是国人开发的一套框架,2016年出来的,现在已更新到2.X版本了。比较新,轻量级,样式简单好看(目前官网已下架,开源了)
2.bootstrap 相对来说是比较成熟的一个框架,现在已经更新到4.X版本。是一个很成熟的框架,这个大部分人一般都用过
1)适用范围不一样
1.layui 其实更偏向与后端开发人员使用,在服务端页面上有非常好的效果。
2.适合做后台框架
3.layui是提供给后端开发人员最好的ui框架,基于DOM驱动,在实现前端交互上比较麻烦,页面的增删改查都需要查询DOM元素。所以在不需要交互的时候,用layui还是不错的(说这句话的人,只能说明你对layui不了解)
4.bootstrap 在前端响应式方面做得很好,PC端和移动端表现都不错。
5.适合做网站
6.如果是类似官网,且需要同时满足PC端和移动端效果,bootstrap 表现很好,但是如果是要交互的网站,比如商城之类,layui显然更好,前后端分离
2)大小不一样
1.layui 轻量级
2.bootsrap 因为成熟,所以使用方便,但是同时也是因为成熟,就显得有些冗余
3. layui和easyui对比
1.easyui 是非开源的,有需要解决的问题的话,就只能等官方更新了
2.layui是开源的,社区比较活跃,解决问题还是比较快的
3.easyui诞生的早些,所以功能相对完善一些,很多功能都能是比较健全的
4.layui就相对来说少一些了,不过,功能都是像官网说的,精雕细琢
5.layui更符合现在的审美
三、基础使用
我们先需进入layui网站
官方网站:https://www.layui.com/(已下线)
参考地址:http://layui.org.cn/demo/index.html(已下线,非官网)
然后,我们点击文档,找到码云,点击进行下载,
这样更方便我们引入一些文件,也能更好地查阅它的组件及开源代码
将layui下载到了本地,那么可将其完整地放置到你的项目目录(或静态资源服务器),并在页面中分别引入:
<!-- 引入 layui.css --> <link rel="stylesheet" href="xxx/layui.css"> <!-- 引入 layui.js --> <script src="xxx/layui.js"></script>
像这样引入后,就可以直接使用啦!!!
导入mvc配置文件和自定义mvcjar包以及一些工具类jar包
用户实体--User
package com.ctb.entity; /** * 用户实体 * @author biao * * 2023年7月10日 */ public class User { private long id; private String name; private String loginName; private String pwd; private long rid; public User() { // TODO Auto-generated constructor stub } @Override public String toString() { return "User [id=" + id + ", name=" + name + ", loginName=" + loginName + ", pwd=" + pwd + ", rid=" + rid + "]"; } public User(long id, String name, String loginName, String pwd, long rid) { super(); this.id = id; this.name = name; this.loginName = loginName; this.pwd = pwd; this.rid = rid; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public long getRid() { return rid; } public void setRid(long rid) { this.rid = rid; } }
BaseDao--通用增删改及分页模糊查询
package com.zking.util; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 所有Dao层的父类 * * @author biao * * @param <T> */ public class BaseDao<T> { /** * 适合多表联查的数据返回 * @param sql * @param pageBean * @return * @throws SQLException * @throws InstantiationException * @throws IllegalAccessException */ public List<Map<String, Object>> executeQuery(String sql, PageBean pageBean) throws SQLException, InstantiationException, IllegalAccessException { List<Map<String, Object>> list = new ArrayList<>(); Connection con = DBAccess.getConnection(); PreparedStatement pst = null; ResultSet rs = null; /* * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...) */ if (pageBean != null && pageBean.isPagination()) { // 必须分页(列表需求) String countSQL = getCountSQL(sql); pst = con.prepareStatement(countSQL); rs = pst.executeQuery(); if (rs.next()) { pageBean.setTotal(String.valueOf(rs.getObject(1))); } // 挪动到下面,是因为最后才处理返回的结果集 // -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%' // -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据 // -- countSql=select count(1) from (sql) t 符合条件的总记录数 String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据 pst = con.prepareStatement(pageSQL); rs = pst.executeQuery(); } else { // 不分页(select需求) pst = con.prepareStatement(sql);// 符合条件的所有数据 rs = pst.executeQuery(); } // 获取源数据 ResultSetMetaData md = rs.getMetaData(); int count = md.getColumnCount(); Map<String, Object> map = null; while (rs.next()) { map = new HashMap<>(); for (int i = 1; i <= count; i++) { // map.put(md.getColumnName(i), rs.getObject(i)); map.put(md.getColumnLabel(i), rs.getObject(i)); } list.add(map); } return list; } /** * * @param sql * @param attrs * map中的key * @param paMap * jsp向后台传递的参数集合 * @return * @throws SQLException * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalArgumentException * @throws IllegalAccessException */ public int executeUpdate(String sql, String[] attrs, Map<String, String[]> paMap) throws SQLException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Connection con = DBAccess.getConnection(); PreparedStatement pst = con.prepareStatement(sql); for (int i = 0; i < attrs.length; i++) { pst.setObject(i + 1, JsonUtils.getParamVal(paMap, attrs[i])); } return pst.executeUpdate(); } /** * 批处理 * @param sqlLst * @return */ public static int executeUpdateBatch(String[] sqlLst) { Connection conn = null; PreparedStatement stmt = null; try { conn = DBAccess.getConnection(); // 设置不自动提交 conn.setAutoCommit(false); for (String sql : sqlLst) { stmt = conn.prepareStatement(sql); stmt.executeUpdate(); } conn.commit(); } catch (Exception e) { try { conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); throw new RuntimeException(e1); } e.printStackTrace(); throw new RuntimeException(e); } finally { DBAccess.close(conn, stmt, null); } return sqlLst.length; } /** * 通用的增删改方法 * * @param book * @throws Exception */ public int executeUpdate(String sql, T t, String[] attrs) throws Exception { // String[] attrs = new String[] {"bid", "bname", "price"}; Connection con = DBAccess.getConnection(); PreparedStatement pst = con.prepareStatement(sql); // pst.setObject(1, book.getBid()); // pst.setObject(2, book.getBname()); // pst.setObject(3, book.getPrice()); /* * 思路: 1.从传进来的t中读取属性值 2.往预定义对象中设置了值 * * t->book f->bid */ for (int i = 0; i < attrs.length; i++) { Field f = t.getClass().getDeclaredField(attrs[i]); f.setAccessible(true); pst.setObject(i + 1, f.get(t)); } return pst.executeUpdate(); } /** * 通用分页查询 * * @param sql * @param clz * @return * @throws Exception */ public List<T> executeQuery(String sql, Class<T> clz, PageBean pageBean) throws Exception { List<T> list = new ArrayList<T>(); Connection con = DBAccess.getConnection(); PreparedStatement pst = null; ResultSet rs = null; /* * 是否需要分页? 无需分页(项目中的下拉框,查询条件教员下拉框,无须分页) 必须分页(项目中列表类需求、订单列表、商品列表、学生列表...) */ if (pageBean != null && pageBean.isPagination()) { // 必须分页(列表需求) String countSQL = getCountSQL(sql); pst = con.prepareStatement(countSQL); rs = pst.executeQuery(); if (rs.next()) { pageBean.setTotal(String.valueOf(rs.getObject(1))); } // 挪动到下面,是因为最后才处理返回的结果集 // -- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%' // -- pageSql=sql limit (page-1)*rows,rows 对应某一页的数据 // -- countSql=select count(1) from (sql) t 符合条件的总记录数 String pageSQL = getPageSQL(sql, pageBean);// 符合条件的某一页数据 pst = con.prepareStatement(pageSQL); rs = pst.executeQuery(); } else { // 不分页(select需求) pst = con.prepareStatement(sql);// 符合条件的所有数据 rs = pst.executeQuery(); } while (rs.next()) { T t = clz.newInstance(); Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); f.set(t, rs.getObject(f.getName())); } list.add(t); } return list; } /** * 将原生SQL转换成符合条件的总记录数countSQL * * @param sql * @return */ private String getCountSQL(String sql) { // -- countSql=select count(1) from (sql) t 符合条件的总记录数 return "select count(1) from (" + sql + ") t"; } /** * 将原生SQL转换成pageSQL * * @param sql * @param pageBean * @return */ private String getPageSQL(String sql, PageBean pageBean) { // (this.page - 1) * this.rows // pageSql=sql limit (page-1)*rows,rows return sql + " limit " + pageBean.getStartIndex() + "," + pageBean.getRows(); } }
1.登录
dao方法
package com.ctb.dao; import java.util.List; import com.ctb.entity.User; import com.zking.util.BaseDao; import com.zking.util.PageBean; /** * * @author biao * * 2023年7月10日 */ public class UserDao extends BaseDao<User> { //查询所有 public List<User> list( User user, PageBean pageBean) throws Exception { String sql="select * from t_oa_user"; return super.executeQuery(sql, User.class, pageBean); } //登录 public User login( User user) throws Exception { String sql="select * from t_oa_user where loginName = '"+user.getLoginName()+"' and pwd = '"+user.getPwd()+"' "; List<User> list= super.executeQuery(sql, User.class, null); if(list!=null && list.size()==1) { return list.get(0); }else { return null; } } }
UserAction
package com.ctb.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ctb.dao.UserDao; import com.ctb.entity.User; import com.zking.framework.ActionSupport; import com.zking.framework.ModelDriver; import com.zking.util.PageBean; import com.zking.util.ResponseUtil; /** * * @author biao * * 2023年7月10日 */ public class UserAction extends ActionSupport implements ModelDriver<User> { private User user = new User(); private UserDao ud = new UserDao(); //登录 public void login(HttpServletRequest req, HttpServletResponse resp) { try { User login = ud.login(user); ResponseUtil.writeJson(resp, login); } catch (Exception e) { e.printStackTrace(); } } @Override public User getModel() { return user; } }
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <%@include file="common/header.jsp"%> <link rel="stylesheet" rev="stylesheet" href="${pageContext.request.contextPath}/static/css/login.css" type="text/css" media="all"> <style> body { color: #; } a { color: #; } a:hover { color: #; } .bg-black { background-color: #; } .tx-login-bg { background: url(static/images/bg.jpg) no-repeat 0 0; } </style> </head> <body class="tx-login-bg " style="margin-top: 100px;"> <center> <div class="tx-login-box"> <div class="login-avatar bg-black"> <i class="iconfont icon-wode"></i> </div> <ul class="tx-form-li row"> <li class="col-24 col-m-24"><p> <input type="text" id="username" placeholder="登录账号" class="tx-input"> </p></li> <li class="col-24 col-m-24"><p> <input type="password" id="password" placeholder="登录密码" class="tx-input"> </p></li> <li class="col-24 col-m-24"><p class="tx-input-full"> <button id="login" class="tx-btn tx-btn-big bg-black">登录</button> </p></li> <li class="col-12 col-m-12"><p> <a href="register.jsp" class="f-12 f-gray">新用户注册</a> </p></li> <li class="col-12 col-m-12"><p class="ta-r"> <a href="#" class="f-12 f-gray">忘记密码</a> </p></li> </ul> </div> </center> <script type="text/javascript"> layui.use(['jquery','layer','form'], function() { let $ = layui.jquery; let layer = layui.layer; let form =layui.form; $("#login").click(function() { $.ajax({ url:"${pageContext.request.contextPath}/user.action?methodName=login", dataType:'json', data: { loginName: $("#username").val(), pwd: $("#password").val() }, method: 'post', success: function(data) { if(data) { layer.alert(''+data.name+'登录成功', {icon: 6}); } else { layer.alert('账号密码有误', {icon: 5}); } } }) }) }); </script> </body> </html>
配置mvc.xml
<action path="/user" type="com.ctb.web.UserAction"> </action>
结果演示:
2.注册
dao方法
package com.ctb.dao; import java.util.List; import com.ctb.entity.User; import com.zking.util.BaseDao; import com.zking.util.PageBean; /** * * @author biao * * 2023年7月10日 */ public class UserDao extends BaseDao<User> { //查询所有 public List<User> list( User user, PageBean pageBean) throws Exception { String sql="select * from t_oa_user"; return super.executeQuery(sql, User.class, pageBean); } //登录 public User login( User user) throws Exception { String sql="select * from t_oa_user where loginName = '"+user.getLoginName()+"' and pwd = '"+user.getPwd()+"' "; List<User> list= super.executeQuery(sql, User.class, null); if(list!=null && list.size()==1) { return list.get(0); }else { return null; } } //注册 public int register(User user) throws Exception { String sql = "insert into t_oa_user(name,loginName,pwd,rid) values(?,?,?,0);";// 定义sql语句 return super.executeUpdate(sql,user,new String[] {"name","loginName","pwd"}); } // public static void main(String[] args) throws Exception { // UserDao u = new UserDao(); // int register = u.register(new User(12, "彪", "ctb", "123", 0)); // // System.out.println(register); // } }
UserAction
package com.ctb.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ctb.dao.UserDao; import com.ctb.entity.User; import com.zking.framework.ActionSupport; import com.zking.framework.ModelDriver; import com.zking.util.PageBean; import com.zking.util.ResponseUtil; /** * * @author biao * * 2023年7月10日 */ public class UserAction extends ActionSupport implements ModelDriver<User> { private User user = new User(); private UserDao ud = new UserDao(); //登录 public void login(HttpServletRequest req, HttpServletResponse resp) { try { User login = ud.login(user); ResponseUtil.writeJson(resp, login); } catch (Exception e) { e.printStackTrace(); } } //注册 public void register(HttpServletRequest req, HttpServletResponse resp) { try { int register = ud.register(user); if (register > 0) { ResponseUtil.writeJson(resp, "OK"); } else { ResponseUtil.writeJson(resp, "NO"); } } catch (Exception e) { e.printStackTrace(); } } @Override public User getModel() { return user; } }
register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <%@include file="common/header.jsp"%> <link rel="stylesheet" rev="stylesheet" href="${pageContext.request.contextPath}/static/css/login.css" type="text/css" media="all"> <style> body { color: #; } a { color: #; } a:hover { color: #; } .bg-black { background-color: #; } .tx-login-bg { background: url(static/images/bg.jpg) no-repeat 0 0; } </style> <script type="text/javascript"> layui.use(['jquery','layer','form'], function() { let $ = layui.jquery; let layer = layui.layer; let form =layui.form; $("#register").click(function() { $.ajax({ url:"${pageContext.request.contextPath}/user.action?methodName=register", dataType:'json', data: { name:$("#relname").val(), loginName: $("#username").val(), pwd: $("#password").val() }, method: 'post', success: function(data) { if(data=="OK") { layer.alert('注册成功', {icon: 6}); location.href="login.jsp"; } else { layer.alert('注册失败', {icon: 5}); } } }) }) }); </script> </head> <body class="tx-login-bg " style="margin-top: 100px;"> <center> <div class="tx-login-box"> <div class="login-avatar bg-black"> <i class="iconfont icon-wode"></i> </div> <ul class="tx-form-li row"> <li class="col-24 col-m-24"><p> <input type="text" id="relname" placeholder="姓名" class="tx-input"> </p></li> <li class="col-24 col-m-24"><p> <input type="text" id="username" placeholder="账号" class="tx-input"> </p></li> <li class="col-24 col-m-24"><p> <input type="password" id="password" placeholder="密码" class="tx-input"> </p></li> <li class="col-24 col-m-24"><p class="tx-input-full"> <button id="register" class="tx-btn tx-btn-big bg-black">注册</button> </p></li> <li class="col-12 col-m-12"><p> <a href="login.jsp" class="f-12 f-gray">返回登录</a> </p></li> </ul> </div> </center> </body> </html>
结果演示:
五、如何扩展一个layui(自定义模块)
1.创建一个新的JavaScript文件,命名为"myLayui.js"(或其他你喜欢的名称)。
注:不用放入layui目录
2.在该文件中,使用layui.define函数定义一个自定义模块。可以使用layui的其他内置模块或第三方库来辅助开发自定义模块。例如:
layui.define(['jquery'], function(exports){ var $ = layui.jquery; // 定义自定义模块的方法 var myModule = { sayHello: function(str){ alert('Hello '+ (str); }, // 添加其他自定义方法... }; // 导出模块接口 exports('myLayui', myLayui); });
以上示例中,我们使用layui.define函数定义了一个名为"myLayui"的自定义模块,并在其中定义了一个名为"sayHello"的方法。这个示例中使用了layui的内置模块jquery作为依赖,所以确保在使用自定义模块前,已经正确引入了jQuery库。
3.在HTML页面中引入layui和自定义模块的JavaScript文件:
<script src=".../layui.js"></script> <script src=".../myLayui.js"></script>
注:确保在引入该模块之前,先引入layui.js
4.在需要使用自定义模块的地方,使用layui.use函数来引入并调用该模块。例如:
layui.use(['myLayui'], function(){ var myLayui = layui.myLayui; // 使用自定义模块的方法 myLayui.sayHello(' Word!!!');//弹出Hello World!!! });
在示例中,我们使用layui.use函数引入了"myLayui"模块,并通过layui.myLayui获取了对该模块的实例。然后,我们可以调用自定义模块的方法,例如sayHello()。
好啦,layui入门就分享到这啦!!!💕