介绍
官方网址:https://www.thymeleaf.org/
官方文档地址:https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.pdf
thymeleaf是Spring推荐使用的模板引擎
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
默认格式与前后缀
我们通过查看spring boot的自动配置文档可知,使用thymeleaf的时候,对页面进行解析会自动拼接前后缀,默认支持html页面类型。
例如,我们return一个hello.html页面回来,只需要return “hello”,会自动拼接前后缀,即classpath:/templates/+hello+.html
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8"); //默认编码类型
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
public static final String DEFAULT_PREFIX = "classpath:/templates/"; //前缀
public static final String DEFAULT_SUFFIX = ".html"; //后缀
导入名称空间
我们在编写html文件的时候,需要使用thymeleaf的语法才能取到对应的值,我们需要导入名称空间,否则没有语法提示
<!DOCTYPE html>
<!--导入名称空间-->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello</h1>
</body>
</html>
初窥thymeleaf
java文件
//@RestController
@Controller
@RequestMapping("/seller/order")
public class SellOrderController {
@Autowired
private OrderServiceImpl orderService;
@GetMapping("/list")
public ModelAndView list(Map<String,Object> map) { //map默认会放在请求域中
map.put("hello","我爱你");
return "order/list";
}
}
html
<!DOCTYPE html>
<!--导入名称空间-->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>hello</h1>
<!--取出hello-->
<div th:text="${hello}">这里是默认值哦</div>
</body>
</html>
我们通过设置th:text="${hello}"
就可以将默认值进行修改
th:语法规则
上面我们介绍了使用th替换默认值,我们写的是text,也就是块块里面的东西,其实所有原生属性都可以替换,例如id、class等等,都可以先写一个默认值,再使用th来改变。
在官方文档,列举了哪些属性先解析,哪些属性后解析
标准表达式语法
-
简单的表达式:
-
获取变量表达式: ${…}
-
选择变量表达式: *{…}
-
与** ∗ ∗ 类 似 , 配 合 t h : o b j e c t = " {}**类似,配合th:object=" ∗∗类似,配合th:object="{session.user}",可以使用*替代上面的元素
-
<div th:object="${session.user}"> <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p> </div>
-
-
消息表达式: #{…}
-
链接URL表达式: @{…}
-
@{/order/process(execId=${execId},execType='FAST')}
-
-
片段表达式: ~{…}
-
-
字面
- 文本文字: ‘one text’ , ‘Another one!’ ,…
- 号码文字: 0 , 34 , 3.0 , 12.3 ,…
- 布尔文字: true , false
- null文本: null
- 文字标记: one , sometext , main ,…
-
文本操作:
- 字符串连接: +
- 文字替换: |The name is ${name}|
-
算术运算:
- 二元运算符: + , - , ***** , / , %
- 减号(一元运算符): -
-
布尔操作:
- 二元运算符: and , or
- 布尔否定(一元运算符): ! , not
-
比较和平等:
- 比较: > , < , >= , <= ( gt , lt , ge , le )
- 大于号、小于号在html里是特殊字符,我们可以使用括号内的东西替代
- 平等运营商: == , != ( eq , ne )
- 比较: > , < , >= , <= ( gt , lt , ge , le )
-
有条件的经营者:
- 如果 - 则: (if) ? (then)
- 如果 - 则 - 否则: (if) ? (then) : (else)
- 三元运算符
- 默认: (value) ?: (defaultvalue)
-
特殊记号:
- 无操作: _
所有这些特征可以被组合并嵌套:
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
行内写法
不是写${},而是写[[…]]或者[(…)],前者表示th:text,后者表示th:utext
综合案例
java
@Controller
punlic class HelloController() {
@ResponseBody;
@RequestMapping("/success");
public String success(Map<String,Object> map) {
map.put("hello","<h1>你好</h1>");
map.put("user",Array.asList("zhangsan","lisi","wangwu"));
return "success";
}
}
html
<!DOCTYPE html>
<!--导入名称空间-->
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功</h1>
<!--th:text 将div的文本内容设置为-->
<div id="div01" class="myDiv" th:id="${hello}" th:class="${hello}" th:text="${hello}">这里显示的是欢迎信息</div>
<br>
<!--th:utext 不会转义特殊字符,会直接做出来一个h1标签,但是text不会,会显示<h1>你好</h1>-->
<div th:text="${hello}">这里显示的是欢迎信息</div>
<div th:utext="${hello}">这里显示的是欢迎信息</div>
<br>
<!--遍历-->
<h4 th:text="${user}" th:each="user:${users}"></h4>
<br>
<!--行内写法-->
<h4>
<span th:each="user:${users}">[[${user}}]]</span>
</h4>
</body>
</html>
效果
循环产生一段连续的数字
<li th:each="index:${#numbers.sequence(0,10)}">
<a href="#" th:text="${index}"></a>
</li>
thymeleaf做if判断
Thymeleaf 的条件判断是 通过 th:if 来做的,只有为真的时候,才会显示当前元素
<p th:if="${testBoolean}" >如果testBoolean 是 true ,本句话就会显示</p>
取反可以用not, 或者用th:unless.
<p th:if="${not testBoolean}" >取反 ,所以如果testBoolean 是 true ,本句话就不会显示</p>
<p th:unless="${testBoolean}" >unless 等同于上一句,所以如果testBoolean 是 true ,本句话就不会显示</p>
除此之外,三元表达式也比较常见
<p th:text="${testBoolean}?'当testBoolean为真的时候,显示本句话,这是用三相表达式做的':''" ></p>
例如,我想判断,当当前页与请求的页相同时,设置不可点击
<li th:each="index:${#numbers.sequence(1,orderDTOPage.getTotalPage())}" th:class="${index==orderDTOPage.getIndex()}? disabled" >
<a href="#" th:text="${index}"></a>
</li>
如果这么写就不对,这样只会产生一页,好好看一下逻辑关系
<li th:each="index:${#numbers.sequence(1,orderDTOPage.getTotalPage())}" th:if="${index==orderDTOPage.getIndex()}" class="disabled">
<a href="#" th:text="${index}"></a>
</li>
实现url参数传递
<a th:href="@{/seller/order/list(page=${index},size=${10})}" th:text="${index}"></a>
开始以/开头表示在根目录下拼接,也可以写成绝对路径
传值到script
<script th:inline="javascript">
var url = [[${url}]];
//三秒跳转
setTimeout('location.href=url',3000);
</script>
注:script标签中 th:inline 一定不能少,通常在取值的前后会加上不同的注释
Thymeleaf一个HTML文件A中引入另一张HTML文件B
HTML A
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:http="http://www.w3.org/1999/xhtml" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<div th:fragment="myfooter">
<div class="footer">
<--footer内容-->
</div>
</div>
</html>
HTML B
<div th:replace="common/footer :: myfooter" ></div>
静态资源文件
建议直接使用th:href=@{}
,否则还要考虑文件的相对路径,还可能导致没加url的自定义前缀