# 模块布局

# 概述

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

# 公共文件

  • 头部文件
<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>{$siteName}</title>
	<link href="__ADMIN__/assets/images/favicon.ico" rel="icon">
	<link rel="stylesheet" href="__ADMIN__/assets/libs/layui/css/layui.css"/>
	<link rel="stylesheet" href="__ADMIN__/assets/module/admin.css?v={$Think.env.app_debug?time():'2.0.7'}"/>
	<!--[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" src="__ADMIN__/assets/libs/layui/layui.js"></script>
	<script type="text/javascript" src="__ADMIN__/assets/js/common.js?v=318"></script>
	<script type="text/javascript">
		var C = '{$app}';
		var A = '{$act}';
		var mUrl = "/";
		var cUrl = "/" + C;
		var aUrl = cUrl+"/"+A;
	</script>
</head>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • 脚本文件
<script type="text/javascript" src="__ADMIN__/module/think_{$app}.js"></script>
1
  • 基类文件
<!DOCTYPE html>
<html>
<!-- 引入头部 -->
{include file='/public/header' /}
<body class="bg-white">
<!-- 正文内容 -->
{__CONTENT__}
<!-- 引入脚部 -->
{include file='/public/footer' /}
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11

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

# 举例实现

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

  • 列表页

<!-- 引入基类模板 -->
{extend name='public/base' /}

<!-- 主体部分 -->
{block name='content'}

	<!-- 功能操作区一 -->
	<form class="layui-form toolbar">
		<div class="layui-form-item">
			<div class="layui-inline">
				<label class="layui-form-label w-auto">职级名称:</label>
				<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" style="width: auto;">
					{widget:query name="查询"}
					{widget:add name="添加职级"}
					{widget:dall name="批量删除"}
				</div>
			</div>
		</div>
	</form>

	<!-- TABLE渲染区 -->
	<table class="layui-hide" id="tableList" lay-filter="tableList"></table>
	
	<!-- 操作功能区二 -->
	<script type="text/html" id="toolBar">
		{widget:edit name="编辑"}
		{widget:delete name="删除"}
	</script>

{/block}
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

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

  • 编辑页
<form class="layui-form model-form" action="">
	<input name="id" id="id" type="hidden" value="{$info.id|default=0}">
	<div class="layui-form-item">
		<label class="layui-form-label">职级名称:</label>
		<div class="layui-input-block">
			<input name="name" value="{$info.name|default=''}" 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">
			{common:switch name="status" title="是|否" value="isset($info['status']) ? $info['status'] : 1"}
		</div>
	</div>
	<div class="layui-form-item">
		<label class="layui-form-label">序号:</label>
		<div class="layui-input-block">
			<input name="sort" id="sort" value="{$info.sort|default=125}" lay-verify="required|number" autocomplete="off" placeholder="请输入序号" class="layui-input" type="text">
		</div>
	</div>
	{widget:submit name="submit|立即保存,close|关闭"}
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

总结:编辑页使用了模板布局,前提是系统需开启模板布局支持,前面的章节我们有具体的介绍,如有不清楚的同学请移至《布局配置》,当然根据业务需要也可以对布局进行灵活控制:

  1. 开启模板布局:$this->app->view->layout(true);;
  2. 关闭模板布局:$this->app->view->layout(false);;
  • 模块JS
/**
 * 职级管理
 * @author 牧羊人
 * @since 2020/7/4
 */
layui.use(['function'], function () {
    //声明变量
    var func = layui.function
        , $ = layui.$;

    if (A == 'index') {
        //【TABLE列数组】
        var cols = [
            {type: 'checkbox', fixed: 'left'}
            , {field: 'id', width: 80, title: 'ID', align: 'center', sort: true, fixed: 'left'}
            , {field: 'name', width: 300, title: '职级名称', align: 'center'}
            , {
                field: 'status',
                width: 100,
                title: '状态',
                align: 'center',
                templet: '#statusTpl',
                sort: true,
                templet: function (d) {
                    var str = "";
                    if (d.status == 1) {
                        str = '<span class="layui-btn layui-btn-normal layui-btn-xs">在用</span>';
                    } else {
                        str = '<span class="layui-btn layui-btn-normal layui-btn-xs layui-btn-danger">停用</span>';
                    }
                    return str;
                }
            }
            , {field: 'sort', width: 80, title: '排序', align: 'center'}
            , {field: 'create_user_name', width: 100, title: '创建人', align: 'center'}
            , {field: 'create_time', width: 180, title: '创建时间', align: 'center', sort: true}
            , {field: 'update_time', width: 180, title: '更新时间', align: 'center', sort: true}
            , {fixed: 'right', width: 150, title: '功能操作', align: 'center', toolbar: '#toolBar'}
        ];

        //【渲染TABLE】
        func.tableIns(cols, "tableList");

        //【设置弹框】
        func.setWin("职级", 500, 300);
    }
});
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
44
45
46
47

以上是实现当前模块职级管理所需要的JS,里面调用了系统JS组件,在章节《JS组件》中我们做过详细的介绍,如有不理解的同学可以查阅前面的文档;

# 实现效果

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

  • 职级列表

    mixureSecure

  • 职级添加/编辑

    mixureSecure

  • 职级删除

    mixureSecure

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