02- Thymeleaf 入门

ThymeLeaf

模板引擎

含义

1、市面上主流的 Java 模板引擎有:JSP、Velocity、Freemarker、Thymeleaf
2、JSP 本质也是模板引擎,Spring Boot 官方推荐使用 “Thymeleaf”模板引擎
3、模板引擎原理图如下,模板引擎的作用都是将模板(页面)和数据进行整合然后输出显示,区别在于不同的模板使用不同的语法,如 JSP 的JSTL表达式,以及J SP 自己的表达式和语法,同理 Thymeleaf 也有自己的语法

在这里插入图片描述

ThymeLeaf入门

官网介绍

Thymeleaf 官网:https://www.thymeleaf.org/

1.Thymeleaf is a modern server-side Java template engine for both web and standalone environments.
Thymeleaf是⾯向Web和独⽴环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚⾄纯⽂本。

2.Thymeleaf's main goal is to bring elegant natural templates to your development workflow — HTML that can be correctly displayed in browsers and also work as static prototypes, allowing for stronger collaboration in development teams.
Thymeleaf旨在提供⼀个优雅的、⾼度可维护的创建模板的⽅式。 为了实现这⼀⽬标,Thymeleaf建⽴在⾃然模板的概念上,将其逻辑注⼊到模板⽂件中,不会影响模板设计原型。 这改善了设计的沟通,弥合了设计和开发团队之间的差距。

3.With modules for Spring Framework, a host of integrations with your favourite tools, and the ability to plug in your own functionality, Thymeleaf is ideal for modern-day HTML5 JVM web development — although there is much more it can do.
对于Spring框架模块,一个允许你集成你最喜欢的工具的平台,并且能够插入自己的功能,Thymeleaf是理想的现代JVM HTML5 web开发工具,虽然它可以做得多。

优势体会

1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。

2.Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。

3.Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

官网示例代码

<table>
  <thead>
    <tr>
      <th th:text="#{msgs.headers.name}">Name</th>
      <th th:text="#{msgs.headers.price}">Price</th>
    </tr>
  </thead>
  <tbody>
    <tr th:each="prod: ${allProducts}">
      <td th:text="${prod.name}">Oranges</td>
      <td th:text="${#numbers.formatDecimal(prod.price, 1, 2)}">0.99</td>
    </tr>
  </tbody>
</table>

SpringBoot 集成 Thymeleaf

导入依赖

<!-- 引入thymeleaf模板引擎-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

默认规则

默认前缀:DEFAULT_PREFIX = "classpath:/templates/"
默认后缀:DEFAULT_SUFFIX = ".html"
类似于 Spring MVC 的视图解析器

案例书写

后台代码

@RequestMapping("hello")
public String hello(Model model){
    model.addAttribute("name","张三");
    return "success";
}

前端页面

<h1 th:text="${name}">hehe</h1>

需要注意的配置文件

# thymeleaf 配置信息
# 前缀最后别忘了添加一个 / (多么痛的领悟)
spring.thymeleaf.prefix=classpsth:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.mode=HTML5
# 代码测试 需要禁用缓存, 生产环境下可以设置为 true
spring.thymeleaf.cache=false

常用标签

添加命名空间, 作用是提示信息

<html lang="en" xmlns:th="http://www.thymeleaf.org">

文本

model.addAttribute("a","<b>你好</b>");
model.addAttribute("b","<b>你好</b>");
<a th:text="${a}"></a>  显示结果为 <b>你好</b>
将内容完整的显示出来 标签也不会 转义
<a th:utext="${b}"></a> 显示结果为 加粗之后的 你好
如果内容中有标签存在, 则将标签转义

日期格式

<h1 th:text="${#dates.format(phone.birthday,'yyyy-MM-dd HH:mm:ss')}"></h1>

简化对象获取功能

<tr>
    <td th:text="${phone.name}"></td>
    <td th:text="${phone.gender}"></td>
    <td th:text="${phone.birthday}"></td>
    <td th:text="${phone.address}"></td>
</tr>

简化为

<tr th:object="${phone}">
    <td th:text="*{name}"></td>
    <td th:text="*{gender}"></td>
    <td th:text="*{birthday}"></td>
    <td th:text="*{address}"></td>
</tr>

URL 路径显示

th:src="@{}"

th:href="@{}"

th:action="@{}"

<script th:src="@{js/test.js}"></script>
<script th:src="@{/js/test.js}"></script>
<script src="/js/test.js"></script>

传递参数

<a href="" th:href="@{/demo(name=张三)}">访问后台demo</a>
<a href="" th:href="@{/demo(name=张三,age=20)}">访问后台demo</a>

加载静态文件

静态文件在 SpringBoot中的默认配置

# 默认配置 , 写不写都是如此
spring.mvc.static-path-pattern=classpath:/static/**

算术与逻辑运算

Thyme Leaf 标准表达式⽀持算术运算:+, - ,*,/(除),%(取余)
表达式中的值可以与 >,<,>= ,<= ,==,!= 符号进⾏⽐较。 
⼀个更简单的替代⽅案是使⽤这些运算符的⽂本别名:
	gt(>),lt(<),ge(>=),le(<=),eq(==),neq(!=)。

逻辑运算符:and(与)、or(或)、!(非),not(非)

条件判断

<h1 th:if="${age} gt 18">年龄大于18</h1>
<h1 th:if="${age} lt 18">年龄小于18</h1>

表单

th:id
th:name
th:value
th:checked
th:selected

条件分支

if

<p th:if="true">th:if="true"</p>

需要注意的是 :

1)如果表达式结果为布尔值,则为 true 或者 false
2)如果表达式的值为 null,th:if 将判定此表达式为 false
3)如果值是数字,为 0 时,判断为 false;不为零时,判定为 true
4)如果 value 是 String,值为 “false”、“off”、“no” 时,判定为 false,否则判断为 true,字符串为空时,也判断为 true
5)如果值不是布尔值,数字,字符或字符串的其它对象,只要不为 null,则判断为 true

switch

<!--字符串类型-->
<div th:switch="'For China'">
    <p th:case="'For USA'">美国</p>
    <p th:case="'For UK'">英国</p>
    <p th:case="'For China'">中国</p>
    <p th:case="*">未知国籍</p>
</div>

循环

基本语法

<table  >
    <tr th:each="stu:${list}">
        <td th:text="${stu.name}"></td>
        <td th:text="${stu.age}"></td>
        <td th:text="${stu.address}"></td>
    </tr>

</table>

循环状态属性

th:each=“stu,varstatus:${list}”

<table  >
    <tr th:each="stu,varstatus:${list}">
        <td th:text="${varstatus.count}"></td>
        <td th:text="${stu.name}"></td>
        <td th:text="${stu.age}"></td>
        <td th:text="${stu.address}"></td>
    </tr>
</table>

属性

使⽤ th:each 时,Thymeleaf 提供了⼀种⽤于跟踪迭代状态的机制:状态变量。状态变量在每个 th:each 属性中定义,幷包含以下数据:

1)index 属性:当前迭代索引,从0开始

2)count 属性:当前的迭代计数,从1开始

3)size 属性:迭代变量中元素的总量

4)current 属性:每次迭代的 iter 变量,即当前遍历到的元素

5)even/odd 布尔属性:当前的迭代是偶数还是奇数。

6)first 布尔属性:当前的迭代是否是第⼀个迭代

7)last 布尔属性:当前的迭代是否是最后⼀个迭代。

<table border="1">
    <thead>
    <tr>
        <th>序号</th>
        <th>工号</th>
        <th>姓名</th>
        <th>生日</th>
        <th>是否已婚</th>
        <th>工资</th>
    </tr>
    </thead>
    <tbody>
    <!-- 遍历集合,如果被遍历的变量 userList 为 null 或者不存在,则不会进行遍历,也不报错-->
    <!-- 设置状态变量 loopStatus,逗号分隔,当为奇数行时,设置一个 css2 样式-->
    <tr th:each="user,loopStatus: ${userList}" th:class="${loopStatus.odd}?'css2'">
        <!-- 显示当前的行序号-->
        <td th:text="${loopStatus.count}"></td>
        <!-- 将用户的主键 uId 存在在 name 属性中-->
        <td th:text="${user.uId}" th:name="${user.uId}"></td>
        <td th:text="${user.uName}"></td>
        <!-- 使用dates对象格式化日期-->
        <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd HH:mm')}"></td>
        <!-- 三运运算判断是否已婚-->
        <td th:text="${user.isMarry}?'是':'否'"></td>
        <td th:text="${user.price}"></td>
    </tr>
    </tbody>
</table>

属性优先级

​ 当在同⼀个标签中写⼊多个 th:* 属性时会发⽣什么? 例如:

<ul>
   <li th:each="item : ${items}" th:text="${item.description}">Item description here...</li>
</ul>

期望是 th:each 属性在 th:text 之前执⾏,以便得到想要的结果,但是 HTML / XML 标准对于标签属性的渲染顺序没有任何定义, 因此 Thyme Leaf 如果要达到这种效果,必须在属性本身中建⽴优先机制,以确保这些属性按预期⼯作。因此,所有的Thymeleaf 属性都定义⼀个数字优先级,以便确定在标签中按顺序执⾏。优先级清单如下:

Order(顺序) Feature(特征) Attributes(属性)
1 Fragment inclusion th:insert 、th:replace
2 Fragment iteration th:each
3 Conditional evaluation th:if 、th:unless、th:switch、 th:case
4 Local variable definition th:object 、th:with
5 General attribute modification th:attr、 th:attrprepend、th:attrappend
6 Specific attribute modification th:value、 th:href、 th:src…
7 Text (tag body modification) th:text 、th:utext
8 Fragment specification th:fragment
9 Fragment removal th:remove

​ 这个优先机制意味着与属性位置并无关系,只与属性名有关:

<ul>
   <li th:each="item : ${items}" th:text="${item.description}">Item description here...</li>
</ul>
等价于
<ul>
   <li th:text="${item.description}" th:each="item : ${items}">Item description here...</li>
</ul>

局部变量

​ JSP 中 JSTL 的set 标签 用于设置变量值和对象属性

<c:set var="j" value="${1}"/>

​ th:each 迭代中的 变量 其实就是局部变量,仅在 标签范围内可⽤,包括所有子元素,可⽤于在该标签中执⾏优先级低于 th:each 的任何其他 th:* 属性。

​ Thymeleaf 中可以使用 th:with 进行指定局部变量,局部变量是指定义在模版⽚段中的变量,并且该变量的作⽤域为所在的模版⽚段。

<div th:with="firstPer=${persons[0]}">
   <p>The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.</p>
</div>
当 th:with 被处理时,firstPer 变量被创建为局部变量并被添加到来⾃上下⽂ map 中,以便它可以与上下⽂中声明的任何其他变量⼀起使⽤,但只能在包含的 <div> 标签内使⽤。

2)可以使用同时定义多个变量,用逗号隔开:

<div th:with="firstPer=${persons[0]},secondPer=${persons[1]}">
   <p>The name of the first person is <span th:text="${firstPer.name}">Julius Caesar</span>.</p>
   <p>But the name of the second person is<span th:text="${secondPer.name}">Marcus Antonius</span>.</p>
</div>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章