1.最近公司准备开发新的项目,准备采用layui做为前端的技术,所以紧急突击学习了这一类的知识,现在把相关的技术点整理整理。
2.LayUI说好也好,说不好也不好,我理解的是他是一个正在成长的框架技术,包括树结构和一些页面效果我觉得还是有欠缺的地方,算了,直接聊技术吧。
3.本博客主要介绍layui的一些控件,页面效果,树结构,以及和后台的一个联动,在这些的基础上做出一个简易的增删查改,感觉还是有收获的。接下来就干货上车,大家拿走。
4.首先是界面原型图,大家看上一看
整体就是左右构造,在加上一些相应的功能。接下来说一下页面效果吧。
5.页面布局
说一下我觉得不好理解的东东吧(其实到后面就觉得都还好了~~~~)
第一个我要吐槽一下layui
就是不给你一个查询的按钮组,还要你自己去文档的上面慢慢找,,,无奈
但是这个组件直接在上面加相应的点击事件就行了。
这里要说一下,并不是用我们平常的input就可以把他们放在一行,而是要用layui的一个控件组,用它的话就可以将他们放在一行
就是这么一个组件套餐,首先用第一个红线处包括生成一个div,其次用class="layui-inline"控件放到上一个div中,最后给定相应的宽度即可。
页面控件上的东西我觉得还是要大家多学多用,我也很多都没怎么用过,只有自己踩过这些坑,你才懂别人跳进去的感受,接下来讲点真正的干货。
我的页面上采用layui,后台是springboot+mybatis+redis+mysql 我就说一下前后端的结合使用。
首先是查询,前台是layui的控件,直接采用文档中的自定义渲染进行查询即可。
<table class="layui-table"
lay-data="{id: 'table1',height: 'full-110', cellMinWidth: 80, page: true, limit:10, url:'/emCompanyInfos/getCompanyInfoList'}">
<thead>
<tr>
<th lay-data="{type:'checkbox'}">序号</th>
<th lay-data="{field:'companyName', width:200, sort: true}">企业名称</th>
<th lay-data="{field:'companyThirdNo', width: 150}">第三方编号</th>
<th lay-data="{field:'companyId', width:150}">企业编号</th>
<th lay-data="{field:'authorizerName', width:150}">授权人姓名</th>
<th lay-data="{field:'authorizerTel', width:150}">授权人姓名</th>
<th lay-data="{field:'',}">运营管理员</th>
<th lay-data="{field:'',}">账户余额</th>
<th
lay-data="{field:'companyState',templet: '#rendererCompanyState'}">企业状态</th>
<th lay-data="{field:'payType',templet: '#rendererPayType'}">支付方式</th>
<th
lay-data="{field:'companyType', sort: true,align: 'right',templet: '#rendererCompanyType'}">企业属性</th>
<th
lay-data="{field:'createTime', width:200,sort: true,align: 'right'}">创建时间</th>
</tr>
</thead>
</table>
在上图中我们可以看到,直接在table中给出自己自定义的风格进行定义,在里面定义请求的url路径,table表格的宽度,page分页的相关属性等等
接下来说一下修改和增加吧,这两个其实是一类的,都是实现相应的弹出层,一个带参数,一个不带参数,我就直接说修改吧。
修改,怎么说呢,在前端就是姚获取你选中的当前行,然后把选中行的数据进行存储,在修改页面进行克隆显示即可,实话,由于官方文档不是那么友好,我着实头疼了很久。
function toUpdate() {
var checkStatus = table.checkStatus('table1');
var datas = checkStatus.data;
var length = checkStatus.data.length;
if (length != 1) {
layer.alert("请选择一行数据");
} else {
layer.open({
type : 2 //此处以iframe举例
,
title : '修改企业信息',
area : [ '700px', '660px' ],
shade : 0,
maxmin : true,
content : 'updateEmCompanyInfo.html',
success : function(layero, index) {
var body = layer.getChildFrame('body',
index);
var iframeWin = window[layero
.find('iframe')[0]['name']];
iframeWin.setData(datas[0]);
//iframeWin.setData2(tree);
},
end : function() {
location.reload();
}
});
}
前三行,就是这里面的关键代码,获取当前行的数据。这个时候你可以打印输出一下,请记住,这里不是简单的alert弹窗,更不是什么layer.alert,这些没用,因为datas里面是json数据,所以你要进行解析。
layer.alert(JSON.stringify(datas));
返回成功,呵呵,代表你已经拿到你想要拿到的值,接下来去页面克隆取值即可,这一点我在关于miniui的博客上有过详细介绍:http://blog.csdn.net/t_james/article/details/78604018
可以看到,只要理解了上述的三行代码,你会发现就没有难点了。
这里我要说一下模糊查询和条件查询,因为一开始我这边不允许用外键,所以导致我用的是左连接查询,然而lz并没怎么接触这个,所以sql写的费劲,不要说很简单啥的,lz只能说,lz做过之后才知道很简单。。
<if test="params.empName != null and params.empName != ''">
and empName like
concat(concat('%',#{params.empName}),'%')
</if>
<if test="params.empTel != null and params.empTel != ''">
and empTel like concat(concat('%',#{params.empTel}),'%')
</if>
另外很想说,左外连接一定要确定主表,其次你的多个左外连接只用用空格隔开就行了。
<select id="getManyList" resultMap="emempinfo">
SELECT
su.username,
emi.companyId,
emi.companyName,
emi.parentId,
eei.empName,
eei.empTel,
eei.empEmail,
eei.allotQuota,
eei.appVersion,
eei.systemVersion,
eei.systemType,
eei.createTime,
eei.empState
FROM
em_emp_info AS eei
LEFT JOIN sys_user AS su ON eei.userId = su.id
LEFT JOIN em_company_info AS emi ON eei.companyId = emi.companyId
<include refid="where" />
limit #{pageStart}, #{pageSize}
</select>
看来只有自身强大,才能统御代码。。
我能说这里才是干货么,,因为我觉得这里最重要,下面我写的是啥------树,兴奋不!!我并不兴奋。
根据官方文档的介绍,我这边写了一个Tree的实体,其次在这里写一个工具类,但是我的数据库需求有一个缺陷,相关的字段上面用的不是固定的id和字符串,所以用不了递归,虽然我也不是很知道递归,哈哈,然后写了一个扩展性不好的工具类。
public Object getComPany(List<EmCompanyInfo> list){
JSONObject jsonObject = new JSONObject();
List<Tree> code2 = new ArrayList<>();
List code3 = new ArrayList<>();
for(int i = 0; i<list.size();i++){
EmCompanyInfo emCompanyInfo = list.get(i);
String emCompanyCode = emCompanyInfo.getCompanyId();
if (emCompanyCode.length()==8) { //如果区域代码长度为11则代表为父级区域
Tree tree = new Tree();
tree.setName(emCompanyInfo.getCompanyName());
tree.setId(emCompanyCode);
List<Tree> code = new ArrayList<>();
for(int z = 0; z<list.size();z++){
EmCompanyInfo emCompanyInfo2 = list.get(z);
String emCompanyCode2 = emCompanyInfo2.getParentId();
if(emCompanyCode2.equals(emCompanyCode)){ //判断取出的父级id和之前的id是否匹配
//System.out.println(RegionCode2+""+RegionCode+""+emRegionInfo2.getRegionCode());
Tree tree2 = new Tree();
tree2.setName(emCompanyInfo2.getCompanyName());
tree2.setId(emCompanyInfo2.getCompanyId());
code.add(tree2);
}
};
tree.setChildren(code);
code2.add(tree);
}
}
jsonObject.put("name", "公司树根节点");//设置根节点名称
jsonObject.put("spread", "true"); //设置展开状态
jsonObject.put("id","com_");
jsonObject.put("children",code2); //子节点
code3.add(jsonObject); //将你的设置最后装载到集合中
return code3; //返回一个code3
}
因为我只是两层嵌套,所以只是有两个循环,如果是要做成省市县三级级联的效果的话,那就要再套一层,我说的可扩展性不强是在哪里呢,就是第一个if里面所谓的区域代码长度那里,我根据相应的数据库字段长度进行匹配父级机构,这就很难受了。
public Object getManyList(PageTableRequest request){
Map<String,Object> requestParams =request.getParams();
int pageSize = Integer.parseInt(requestParams.get("limit").toString());//分页参数
int pageStart = (Integer.parseInt(requestParams.get("page").toString())-1)*pageSize;//分页起始数据
Object paramsStr = requestParams.get("paramsStr");
Map<String,Object> params = null;//查询参数
if(paramsStr!=null){
params = JSONObject.parseObject(paramsStr.toString(), Map.class);
}
int count = emEmpInfoDao.count(params);
List<EmEmpInfo> list = emEmpInfoDao.getManyList(params,pageStart,pageSize);
JSONObject reData = new JSONObject();
JSONArray datas = new JSONArray();
for (int i = 0; i < list.size(); i++) {
EmEmpInfo emEmpInfo = list.get(i);
datas.add(JSONObject.toJSON(emEmpInfo));
}
reData.put("code",0);
reData.put("msg","");
reData.put("count",count);
reData.put("data",datas);
//System.out.print(reData.toJSONString());
return reData;
}
public Object getManyList(){
EmEmpInfoTreeUtil treeUtil = new EmEmpInfoTreeUtil();
List company = (List) treeUtil.getComPany(emCompanyInfoDao.getManyList());
JSONObject map = new JSONObject();
map.put("nodes", company); //设置节点数据
map.put("elem", "#Tree"); //指定元素的选择器
map.put("click","function(item){layer.msg('admin');console.log(item);}");
return company;
}
这里就是controller里面的逻辑代码,怎么说呢,通过获取公司里面的数据,进入树形结构里面的工具类里面进行遍历,最后显示输出,最下方的是一个点击map进行左右联动,显示相应的树形结构信息。
页面只用和官方文档一样给一个ul li即可,里面加上id即可。
接下来就是给一点js事件,代表页面加载即执行的方法。
window.onload = function() {
getTree();
}
function getTree() {
$.ajax({
type : "GET",
url : "/emCompanyInfos/getManyList",
success : function(data) {
layui.tree({
elem : '#Tree',
nodes : data,
click : function(item) {
console.log(item);
tree = item.name;
//layer.alert(tree);
var paramsStr = '{"companyId":"' + item.id
+ '"}';
table.reload('table1', {
page : {
curr : 1
},
where : {
paramsStr : paramsStr
}
});
}
});
}
});
}
这个是树形结构显示和左右联动的总结性质的代码,所以有点繁琐。大致就是页面加载即调用相应的url,然后查询出相应的树形结构信息显示即可。点击相应的树形节点即可进行左右联动,关键代码就是查询时进行数据后面的模糊查询,在工具类里面进行判断一下前缀即可。
大致就是这样,希望和大家可以相互交流一下。