# 模块布局

# 概述

JavaWeb混编版框架基于模板引擎Thymeleaf,为了简化开发的复杂性和提高开发效率以及增加代码的可维护性,框架在设计支持就要求采用模板布局的技术,把整个页面进行拆分和切割,把公共的部分抽离出来,比如头部脚本内容区,其中头部和脚本是单独建立文件,同时在模板文件中进行引用,同时为了代码的简洁性灵活性可维护性,我们同时又引入了模板继承的技术,在以前我们传统的开发模块式,我们最常见的便是加单的吧文件的头部脚本文件单独抽离作为公共文件来引入,从某种层面来说已经提高了开发效率和代码的可维护性,但是为了进一步增强和提交开发效率,我们同时采用了模板继承技术,下面我们举例职级模块做详细的说明:

# 公共文件

  • 头部文件
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<header>
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
        <title th:text="${fullName} ?: 'JavaWeb后台开发框架'"></title>
        <link href="/static/assets/images/favicon.ico" rel="icon">
        <link rel="stylesheet" th:href="@{/static/assets/libs/layui/css/layui.css}"/>
        <link rel="stylesheet" th:href="@{/static/assets/module/admin.css?v=318}"/>
        <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
        <script type="text/javascript" th:src="@{/static/assets/libs/layui/layui.js}"></script>
        <script type="text/javascript" th:src="@{/static/assets/js/common.js?v=318}"></script>
        <script type="text/javascript">
            var url = window.location.pathname.substring(1);
            var item = url.split("/");
            var C = item[0];
            var A = item[1];
            var cUrl = "/" + C;
        </script>
    </head>
</header>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  • 脚本文件
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<footer>
    <!-- JS部分 -->
    <script type="text/javascript">
        var url = window.location.pathname.substring(1);
        var item = url.split("/");
        var jsUrl = "/static/module/javaweb_" + item[0] + ".js";
        document.write("<script src='" + jsUrl + "'><\/script>");
    </script>
</footer>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
  • 基类文件
<!DOCTYPE html>
<html>
<!-- 引入头部 -->
<header th:replace="./public/header :: header"></header>
<body>
<!-- 正文开始 -->
<div class="layui-fluid">
    <div class="layui-card">
        <!-- 内容区 -->
        <div class="layui-card-body" layout:fragment="content">
            内容区
        </div>
    </div>
</div>
<!-- 引入脚部 -->
<footer th:replace="./public/footer :: footer"></footer>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

小结:从上面的内容我们可以看出,公共模板文件我们拆分为头部文件脚本文件基类文件,在基类文件中我们引入了头部和脚本,中间正文区域便是我们存放具体页面类型的地方了,我们这里做了模板继承layout:fragment="content",所有继承了此基类文件所编写的内容全全部会自动解析到此元素中去,这个不仅方便了我们业务相关的界面,同时我们有可以轻松的维护底层的文件,方便以后升级和维护;

# 举例实现

这里我们以职级管理模块为例,重点给大家介绍了框架是如何使用模板继承的

  • 列表页
<html layout:decorator="public/layout" xmlns:miguo="http://www.w3.org/1999/html">
<div layout:fragment="content">

    <!-- 表格工具栏 -->
    <form class="layui-form toolbar">
        <div class="layui-form-item">
            <div class="layui-inline">
                <div class="layui-input-inline">
                    <input type="text" name="name" placeholder="请输入职级名称" autocomplete="off" class="layui-input">
                </div>
            </div>
            <!-- 状态下拉单选 -->
            <div class="layui-inline">
                <div class="layui-input-inline">
                    <!-- 下拉单选 -->
                    <widget:singleSelect name="status|0|状态|name|id" th:data="${LEVEL_STATUS_LIST}" value="0"/>
                </div>
            </div>
            <div class="layui-inline">
                <div class="layui-input-inline" style="width: auto;">
                    <widget:btnQuery name="查询"/>
                    <widget:btnAdd name="添加职级"/>
                    <widget:btnDAll name="批量删除"/>
                </div>
            </div>
        </div>
    </form>

    <!-- 数据表格 -->
    <table class="layui-hide" id="tableList" lay-filter="tableList"></table>

    <!-- 表格操作列 -->
    <script type="text/html" id="toolBar">
        <widget:btnEdit name="编辑"/>
        <widget:btnDel name="删除"/>
    </script>

    <!-- 状态 -->
    <script type="text/html" id="statusTpl">
        <input type="checkbox" name="status" value="{{ d.id }}" lay-skin="switch" lay-text="正常|停用" lay-filter="status" {{ d.status == 1 ? 'checked' : '' }} >
    </script>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

从上面的内容我们可以看出,当前模块文件继承了模板布局文件public/layout即:public目录下的layout文件,继承内容替换标签为layout:fragment="content",此文件中所有编写的内容将全部经过此标签替换到想用的位置;

  • 编辑页
<html layout:decorator="public/form" xmlns:miguo="http://www.w3.org/1999/html">
<div layout:fragment="content">
	<form class="layui-form model-form" action="">
		<input name="id" type="hidden" th:value="${info['id']}?:0">
		<div class="layui-form-item">
			<label class="layui-form-label">职级名称:</label>
			<div class="layui-input-block">
				<input name="name" th:value="${info['name']}" lay-verify="required" autocomplete="off" placeholder="请输入职级名称" class="layui-input" type="text">
			</div>
		</div>
		<div class="layui-form-item">
			<label class="layui-form-label">状态:</label>
			<div class="layui-input-block">
				<widget:switchCheck name="status" data="正常|停用" th:value="${info['status']} ?: 1"/>
			</div>
		</div>
		<div class="layui-form-item">
			<label class="layui-form-label">显示顺序:</label>
			<div class="layui-input-block">
				<input name="sort" th:value="${info['sort']}" lay-verify="required|number" autocomplete="off" placeholder="请输入显示顺序" class="layui-input" type="text">
			</div>
		</div>
		<widget:btnSubmit name="submit|立即保存,close|关闭"/>
	</form>
</div>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

小结:列表页不同,编辑页基类文件我们单独建立了一个form,当前模块文件集成了基类文件public/form即:public目录下的layout文件,继承了内容替换标签为layout:fragment="content",此文件中所有编写的内容将全部经过此标签替换到想用的位置;

# 实现效果

上述便是Thymeleaf模板引擎、继承相关的技术和实现思路,对模板引擎和继承不太了解的朋友可以自定查阅资料,下面是经过模块拆分、引用、集成之后实现的实际模块效果图:

  • 职级列表

    mixureSecure

  • 职级添加/编辑

    mixureSecure

  • 职级删除

    mixureSecure

下一章节《案例演示》会详细的教大家如何快读的去实现一个完整模块的开发以及模块中具体有哪些文件和实现方法;