thymeleaf
thymeleaf是springboot推荐使用的模板引擎之一,其官网地址为:https://www.thymeleaf.org
thymeleaf-layout-dialect
thymeleaf-layout-dialect是thymeleaf布局框架,可以抽取公共的header,footer,left等html元素和公共的 css,js文件。开发人员只需专注具体的body内容,大大减少了代码冗余,使代码简洁明了,层次清晰。其项目的github地址为:https://github.com/ultraq/thymeleaf-layout-dialect
整合
以springboot项目为例,整合开发thymeleaf布局。
maven坐标:
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- thymeleaf布局 -->
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>2.3.0</version>
</dependency>
编写layout页面
一个典型的layout页面代码如下,为了页面美观,我这里选择了引入了vue + element-ui。
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">skindream</title>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="stylesheet" href="/static/assets/css/index.css"/>
<link rel="stylesheet" href="/static/framework/element-ui/element.css"/>
<link rel="stylesheet" href="/static/plugins/nprogress/nprogress.css"/>
</head>
<body>
<div id="app">
<el-container>
<el-header>
<el-menu mode="horizontal" text-color="#202124" active-text-color="#409eff">
<el-menu-item :index="1"><a href="/">skindream</a></el-menu-item>
<el-menu-item :index="2"><a href="/movies">影视</a></el-menu-item>
<el-menu-item :index="3"><a href="/animation">动画</a></el-menu-item>
<el-menu-item :index="4"><a href="/music">音乐</a></el-menu-item>
<el-menu-item :index="5"><a href="/game">游戏</a></el-menu-item>
<el-menu-item :index="6"><a href="/article">文章</a></el-menu-item>
</el-menu>
<el-menu mode="horizontal">
<el-menu-item index="1"><a href="/login">登录</a></el-menu-item>
</el-menu>
</el-header>
<el-main>
<!-- 这里可以被其他页面替换 -->
<div layout:fragment="content"></div>
</el-main>
<footer>
<el-footer>@skindream</el-footer>
</footer>
</el-container>
</div>
<script src="/static/framework/vue/vue.min.js"></script>
<script src="/static/framework/element-ui/element.js"></script>
<script src="/static/plugins/nprogress/nprogress.js"></script>
<script>
NProgress.start();
NProgress.done();
new Vue({
el: '#app'
})
</script>
</body>
</html>
访问这个layout页面,页面效果如下:

编写content页面
现在编写content页面替换掉中间的空白内容,动画animation.html代码如下:
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorate="/commons/layout">
<head>
<title>动画</title>
<!-- 这里可以引入该页面独有的css文件 -->
<link rel="stylesheet" href="/static/assets/css/animation.css"/>
</head>
<body>
<div layout:fragment="content">
<p>这是动画</p>
</div>
<!-- 这里可以引入该页面独有的js文件 -->
<script src="/static/assets/js/animation.js"></script>
</body>
</html>
其中需要注意的是
layout:decorate="/commons/layout"
需要指定到layout.html
所在的位置,layout:fragment="content"
的content
名称对应的是layout.html
中<div layout:fragment="content"></div>
的名称。定义一个controller,代码如下:
package pers.skindream.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("animation")
public class AnimationController {
@GetMapping
public String toAnimation() {
return "views/animation";
}
}
访问http://localhost:7001/animation,页面效果如下:

title-pattern
layout中有这样一段代码:
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">skindream</title>
$LAYOUT_TITLE - $CONTENT_TITLE
表示页面title
由两部分组成,layout
页面中的title
-content
页面中的title
。我这里表现的就是skindream - 动画
页面参数传递
改造
animation.html
,代码如下:
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
layout:decorate="/commons/layout" th:with="dio='我不做人了,JOJO!'">
<head>
<title>动画</title>
<!-- 这里可以引入该页面独有的css文件 -->
<link rel="stylesheet" href="/static/assets/css/animation.css"/>
</head>
<body>
<div layout:fragment="content">
<p>这是动画</p>
</div>
<!-- 这里可以引入该页面独有的js文件 -->
<script src="/static/assets/js/animation.js"></script>
</body>
</html>
我这里运用
thymeleaf
提高的标签th:with
向layout.html
页面传递了一个参数dio
改造layout.html
接收传递过来的参数,代码如下:
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
<title layout:title-pattern="$LAYOUT_TITLE - $CONTENT_TITLE">skindream</title>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="stylesheet" href="/static/assets/css/index.css"/>
<link rel="stylesheet" href="/static/framework/element-ui/element.css"/>
<link rel="stylesheet" href="/static/plugins/nprogress/nprogress.css"/>
</head>
<body>
<div id="app">
<el-container>
<el-header>
<el-menu mode="horizontal" text-color="#202124" active-text-color="#409eff">
<el-menu-item :index="1"><a href="/">skindream</a></el-menu-item>
<el-menu-item :index="2"><a href="/movies">影视</a></el-menu-item>
<el-menu-item :index="3"><a href="/animation">动画</a></el-menu-item>
<el-menu-item :index="4"><a href="/music">音乐</a></el-menu-item>
<el-menu-item :index="5"><a href="/game">游戏</a></el-menu-item>
<el-menu-item :index="6"><a href="/article">文章</a></el-menu-item>
</el-menu>
<el-menu mode="horizontal">
<el-menu-item index="1"><a href="/login">登录</a></el-menu-item>
</el-menu>
</el-header>
<el-main>
<!-- 这里可以被其他页面替换 -->
<div layout:fragment="content"></div>
</el-main>
<footer>
<el-footer>@skindream - <span th:text="${dio}"></span></el-footer>
</footer>
</el-container>
</div>
<script src="/static/framework/vue/vue.min.js"></script>
<script src="/static/framework/element-ui/element.js"></script>
<script src="/static/plugins/nprogress/nprogress.js"></script>
<script>
NProgress.start();
NProgress.done();
new Vue({
el: '#app'
})
</script>
</body>
</html>
其中
<el-footer>@skindream - <span th:text="${dio}"></span></el-footer>
用于接收参数
再次访问http://localhost:7001/animation,页面效果如下:

总结
以上就是thymeleaf布局的简单应用,纵观下来确实起到了开头所说的开发人员只需专注具体的body内容,大大减少了代码冗余,使代码简洁明了,层次清晰
的作用。