Thymeleaf快速入门

Thymeleaf 是新一代 Java 模板引擎,与 Velocity、FreeMarker 等传统 Java 模板引擎不同,Thymeleaf 支持 HTML 原型,其文件后缀为“.html”,因此它可以直接被浏览器打开,此时浏览器会忽略未定义的 Thymeleaf 标签属性,展示 thymeleaf 模板的静态页面效果;当通过 Web 应用程序访问时,Thymeleaf 会动态地替换掉静态内容,使页面动态显示。从而可以更好地分割开前后端的开发。

搭建Demo

首先创建一个SpringBoot项目,添加lombok、SpringWeb和Thymeleaf

配置文件

在application.yml配置文件中关闭cache缓存

Thymeleaf默认会开启页面缓存,提高页面并发能力,但会导致我们修改页面不会立即被展现,所以开发中最好关闭页面缓存

server:
  port: 8081
spring:
    thymeleaf:
        cache: false

添加thymeleaf模版

在idea的设置中添加一个thymeleaf模版

设置 → 编辑器 → 文件和代码模版

添加一个名为thymeleaf的模版

<!doctype html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>#[[$Title$]]#</title>
</head>
</html>

创建模版后,对着文件夹右键选择新建,就可以看到自己创建的thymeleaf模版

image-20221009143842412

image-20221009144302105

Thymeleaf语法的基本使用

语法标记

  • 简单表达式:

    • 变量表达式:${...}
    • 选择变量表达式:*{...}
    • 消息表达:#{...}
    • 链接URL表达式:@{...}
    • 片段表达式:~{...}
  • 文字

    • 文本文字: 'one text', 'Another one!', ...
    • 号码文字: 0, 34, 3.0, 12.3, ...
    • 布尔文字: true, false
    • 空文字: null
    • 文字标记:one, sometext, main, ...
  • 文字操作:

    • 字符串串联:+
    • 文字替换: [The name is ${name}]
  • 算数运算:

    • 二元运算符: +, -, *, /, %
    • 减号(一元运算符):-
  • 布尔运算:

    • 二元运算符:and, or
    • 布尔否定:!, not
  • 比较和平等:

    • 比较:>, <, >=, <=, (gt, lt, ge, le)
    • 等号运算符: ==, !=, (eq, ne)
  • 条件运算符:

    • 如果-则: (if) ? (then)
    • 如果-则-否则:(if) ? (then) : (else)
    • 默认: (value) ?: (defaultvalue)

使用thymeleaf来渲染模版

可以通过使用thymeleaf的标签语法来达到渲染语句的效果,如下,我们要动态地渲染这个页面的title,可以使用th:text来进行渲染

<!doctype html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${title}">默认的title</title>
</head>
</html>

此时,标签语法中的title并没有被定义,故在实际页面上渲染的标题依然是默认的title

这时需要定义一个控制器来对模版进行渲染,创建一个IndexController

@Controller
public class IndexController {
    @GetMapping("/index")
    public String index(Model model){
        model.addAttribute("title", "传递的title");
        return "index";
    }
}

然后通过访问控制器接口可以看到成功传递了title属性

image-20221009150617605

标签语法渲染的属性可以进行字符串拼接,只需要在前后都加上|

<!doctype html>
<html lang="ch" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="|这是个${title}|">默认的title</title>
</head>
</html>

image-20221009151121500

如果需要渲染页面描述和页面关键字,则可以使用th:content标签

<head>
    <meta charset="UTF-8">
    <title th:text="${title}">默认的标题</title>
    <meta name="description" th:content="${description}">
    <meta name="keywords" th:content="${keywords}">
</head>
@GetMapping("/index")
public String index(Model model) {
    model.addAttribute("title", "传递的标题");
    model.addAttribute("description", "传递的描述");
    model.addAttribute("keywords", "传递的关键字");
    return "index";
}

渲染对象

创建一个实体类UserVO

@Data
public class UserVO {
    private String username;
    private Integer age;
    private Integer sex;
    private Boolean isVip;
    private Date createTime;
    private List<String> tags;
}

在controller中新建一个basic方法,来将user对象传输到页面中

@GetMapping("/basicTrain")
public String basic(Model model) {
    UserVO userVO = new UserVO();
    userVO.setAge(21);
    userVO.setSex(1);
    userVO.setCreateTime(new Date());
    userVO.setTags(Arrays.asList("Java", "PHP", "Node"));
    userVO.setUsername("zoi");
    model.addAttribute("user", userVO);
    return "basic";
}

新建basic.html,通过调用方法的形式来渲染user对象的信息

<div>
    <h2 th:text="${user.getUsername()}"></h2>
    <p th:text="${user.getAge()}"></p>
</div>

还可以不使用get的方式,直接使用属性名

<h2 th:text="${user.username}" ></h2>

也可以用以下方式将user定义为临时变量,然后使用*{xxx}调用

<div th:object="${user}">
    <h2 th:text="*{username}"></h2>
    <p th:text="*{age}"></p>
</div>

th:if 判断

th:if可以通过布尔值决定这个元素是否渲染,为true则渲染,false则不渲染

<p th:if="${user.isVip}">会员</p>

th:each 迭代循环

th:each可以迭代循环出数据,在user对象中tags是一个数组,可以使用以下方式渲染

<ul>
   <li th:each="tag:${user.getTags()}" 
       th:text="${tag}"></li>
</ul>

状态变量在th:each属性中定义,并且包含以下数据:

  • 当前的迭代索引,从0开始。这是index属性。
  • 从1开始的当前迭代索引。这是count属性。
  • 迭代变量中元素的总数。这是size财产。
  • 每次迭代的iter变量。这是current财产。
  • 当前迭代是偶数还是奇数。这些是even/odd布尔属性。
  • 当前迭代是否是第一个。这是first布尔属性。
  • 当前迭代是否为最后一次。这是last布尔属性。

th:switch 选择器

th:switch选择语句,*代表默认

<div th:switch="${user.getSex()}">
    <p th:case="'1'">男</p>
    <p th:case="'2'">女</p>
    <p th:case="*">默认</p>
</div>

th:href 引入静态资源

如果需要通过thymeleaf引入static目录下的静态资源可以使用@{xxx}的方式引用

<link th:href="@{/app.css}" rel="stylesheet">

th:inline 动态渲染

通过th:inline可以动态地渲染JavaScript的代码

<script th:inline="javascript">
    const user = /*[[${user}]]*/{};
    console.log(user)
</script>

同理,css也可以用这种方式渲染

<style th:inline="css">
    .main\ elems {
      text-align: /*[[${align}]]*/ left;
    }
</style>

th:fragment 碎片(组件)

在日常开发中我们经常会将一些可以复用的部分抽离出来,避免重复开发

新建一个compoment.html,一个文件里面可以写多个碎片,使用th:fragment来定义

<footer th:fragment="com1">
    this is com1
</footer>
 
<footer id="com2">
    this is com2
</footer>

定义组件后,通过标签语法来渲染到html,主要有两种方式来使用碎片replaceinsert,在index.html中编写

<!--replace-->
<div th:replace="~{component::com1}"></div>
<!--insert-->
<div th:insert="~{component::com1}"></div>

这两种方式的区别就是,replace会将新标签完全替换原本的标签,也就是说原本写th:replace属性的标签就不会渲染出来,insert是往这个标签内插入标签

image-20221009205753341

通过选择器使用

可以直接通过选择器使用碎片,而不需要通过th:fragment来定义

<footer id="com2">
    this is com2
</footer>

然后可以直接使用它

<div th:insert="~{compoment::#com2}"></div>

注释类型

在碎片中是可以使用控制传递的数据的,比如上面的user对象,但是开发工具在compoment.html页面中可能不能识别到user对象,我们可以打一个注释

<!--/*@thymesVar id="user" type="com.example.thymeleaf.vo.UserVO"*/-->
<h2 th:text="${user.getUsername()}"></h2>

组件传递参数

Thymeleaf中组件也是可以传递数据的

<div th:fragment="com3(message)">
    <p th:text="${message}"></p>
</div>

引用组件

<div th:insert="~{compoment::com3('这是传递的数据')}"></div>

局部替换组件

我们使用一个组件的时候,想要局部替换掉这个组件里面的部分内容该怎么做呢?通过传递参数的方式传递一个组件过来,并把这个组件替换掉原本的一部分

<div th:fragment="com4(message)">
   <p th:replace="${message}">原本的message</p>
</div>

使用的时候

<div th:insert="~{component::com4(~{::#message})}">
    <p id="message">替换的message</p>
</div>

基本对象

ctx:上下文对象

${#ctx.request}
${#ctx.response}
${#ctx.session}
${#ctx.servletContext}

请求/会话属性

${session.xxx}             
${application.xxx}      
${#request.getAttribute('xxx')}

工具类

在thymeleaf里面是可以直接使用一些Java的函数的,并且你可以通过传递参数的方式把一些自己写的方法传递给页面,在里面调用也是可以的

一些可以直接的使用函数

  • \#dates
  • \#calendars
  • \#strings
  • \#numbers
  • \#objects
  • bools

  • \#arrays
  • \#lists
  • \#sets
  • \#maps
  • \#aggregates

以日期格式化来举例:

<!--日期格式化-->
<p th:text="${#dates.format(user.createTime,'yyyy-MM-dd HH:mm')}"></p>   
最后修改:2022 年 10 月 31 日
如果觉得我的文章对你有用,能不能v我50参加疯狂星期四