依赖
- Maven
Thymeleaf基础依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
layout布局依赖
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>2.3.0</version>
</dependency>
- Gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.3.0'
}
thymeleaf方言
- 以th开头的方式,需要在html标签里引入thymeleaf的命名空间:
<html xmlns:th="http://www.thymeleaf.org">
<spanth:text
="..."> - 以data作为前缀,是html5里标准的用于自定义属性的,不需要引入命名空间
<spandata-th-text
="...">
表达式
- 变量表达式:${...}
<span th:text="${data.name}">
- 消息表达式:#{...}
也称之为文本外部化、国际化或i18n,从国际化配置文件里去取key对应的值?不太懂
<table>
<th th:text="#{header.address.city}">...</th>
</table>
- 选择表达式:*{...}
经常与
th:object
替换对象配合使用,th:object="${book}"
首先获取到对象book,"*{}"
对象里取属性。
等于变量表达式${book.title}
,区别是${book}
从整个上下文中取的,*{title}
是从${book}
中取的,执行效率更高。
<div th:object="${book}">
<span th:text="*{title}">...</span>
</div>
链接表达式:@{...}
绝对链接:<a th:href="@{http://www.baidu.com/main}">...</a>
协议相对链接:<a th:href="@{//static/html/initial}">...</a>
服务器相对链接:<a th:href="@{~/contents/main}">...</a>
目录相对链接:<a th:href="@{../docments/report}">...</a>
分段表达式:th:insert、th:replace、th:include(3.0以后不推荐)
被替换的内容:
<footer th:fragment="copy">
<a href="https://www.baidu.com">2019 蟹蟹<a/>
</footer>
执行替换的部分:
<body>
<div th:insert="footer::copy"></div>
<div th:replace="footer::copy"></div>
<div th:include="footer::copy"></div>
</body>
替换效果:
<body>
// 1、insert
<div>
<footer th:fragment="copy">
<a href="https://www.baidu.com">2019 蟹蟹<a/>
</footer>
</div>
// 2、replace
<footer>
<a href="https://www.baidu.com">2019 蟹蟹<a/>
</footer>
// 3、include
<div>
<a href="https://www.baidu.com">2019 蟹蟹<a/>
</div>
</body>
文本替换
- 文本:' ' 单引号引起来表示是文本内容
- 数字:不需要单引号,也支持一些数学计算
<span th:text=" '这是要展示的文本' ">这里的部分会被替换掉</span>
<span th:text=" 1+1 ">这里的部分会被替换掉</span>
属性赋值
th:value
<input th:value = "${user.name}" />
迭代器:th:each
<li th:each="book:${books} th:text="${book.title}"><li>
状态变量:
index:迭代器索引从0开始
count:迭代器索引从1开始
size:迭代器大小
current:当前迭代器值
even/odd:当前索引是偶数/奇数
first/last:第一个/最后一个
- select下拉框数据回显
<select id="gysxz" onchange="getGysbm(this.value)">
<option th:each="gys:${gysList}" th:value="${gys.gysbm}" th:text="${gys.gysmc}" th:selected="${gys.gysmc}"></option>
<option selected>--请选择供应商--</option>
</select>
function getGysbm() {
var option=$("#gysxz option:selected").val();
console.log("选中的值是:"+option);
}
内联表达式
[[...]] 和 [(...)] 分别对应于 th:text 和 th:utext
,前者会对特殊字符进行转义,后者不会对特殊字符转义
激活内联使用th:inline 属性,它有四个模式:text、javascript、css 和 none。
文本内联:
<p th:text="${value}"></p>
等同于:<p th:inline="text">[[${value}]]</p>
JavaScript内联:
<javascript th:inline="javascript">
alert([[${value}]]);
</script>
- CSS内联:
变量:
classname = 'main elems'
align = 'center
内联写法:
<style th:inline="css">
.[[${classname}]]{
text-align:[[${align}]];
}
</style>
转换成这样:
<style th:inline="css">
.main\ elems {
text-align: center;
}
</style>
禁用内联:th:inline=none
<p th:inline="none">A double array looks like this:[[1,2,3],[4,5]]!</p>
其它
th:
标签
th:value
属性赋值<input th:value = "${user.name}" />
页面布局 一
- 通用模板页面
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>公用模板</title>
</head>
<body>
<h1>页头</h1>
<div layout:fragment="content">等待被替换</div>
<h1>页尾</h1>
</body>
</html>
- 标题子页面有则显示子页面的,子页面没有则显示父页面的。
- 子页面 head和body标签并不是必须的。
- 自定义内容页面
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="base">
<!--<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{base.html}">-->
<head>
<meta charset="UTF-8">
<title>新标题</title>
</head>
<body>
<div layout:fragment="content">已经被替换的内容</div>
</body>
</html
页面布局 二
- 在template文件夹新建
fragments
模板存放文件夹,在里面新建header.html
和footer.html
两个模板文件
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:fragment="header">
<h1>Thymeleaf in action</h1>
<a href="/users">首页</a>
</div>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:fragment="footer">
<a href="https://www.baidu.com">百度地址连接</a>
</div>
</body>
</html>
- 新建首页
list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<dvi th:replace="~{fragments/header::header}"></dvi>
<h1>我是中间的内容!</h1>
<dvi th:replace="~{fragments/footer::footer}"></dvi>
</body>
</html>
公共页面数据传递
- 新建全局控制器,用于返回公共页面的数据
/*
@ControllerAdvice的使用场景
1、全局异常处理
2、全局数据绑定:在每一个 Controller 的接口中,都能够访问到这些数据
3、全局数据预处理
*/
/*
使用 @ModelAttribute 注解标记该方法的返回数据是一个全局数据,
默认情况下,这个全局数据的 key 就是返回的变量名,value 就是方法返回值
也可以通过 @ModelAttribute 注解的 name 属性去重新指定 key。
*/
@ControllerAdvice
@ResponseBody
public class globalController {
@ModelAttribute(name="datas")
public ArrayList<String> returnDatas() {
ArrayList<String> list = new ArrayList<>();
list.add("新闻");
list.add("军事");
list.add("游戏");
return list;
}
}
其它
- 获取ModeAndView传来的数据
<script th:inline="javascript"> // 需要添加 th:inline 才能访问 model 中的属性
window.onload = function () {
console.log("页面加载完成");
// 获取ModelAndView中的dbgoods对象
var dbgoods = [[${dbgoods}]];
// 打印
console.log(dbgoods);
}
</script>