Skip to content

11.4 合成标签th:block

th:block 是 Thymeleaf 标准方言中唯一的元素处理器(而非属性)。

它的核心定位是「纯属性容器」——仅用于承载 th:* 属性(如 th:eachth:if),Thymeleaf 执行完这些属性后,会移除 th:block 标签本身,但保留其内部的所有内容。

最常用的场景是:遍历逻辑需要作用于多个相邻标签(而非单个标签),比如表格中每个数据项需要两行 <tr>,此时可以用 th:block 包裹多行 <tr>

html
<table>
    <th:block th:each="user : ${users}">
        <tr>
            <td th:text="${user.login}">...</td>
            <td th:text="${user.name}">...</td>
        </tr>
        <tr>
            <td colspan="2" th:text="${user.address}">...</td>
        </tr>
    </th:block>
</table>

此时用 th:block 包裹多行 <tr> 的好处就体现出来了。

html
<table>
  <!-- th:block 承载遍历属性,执行后自身消失,保留内部两行 tr -->
  <th:block th:each="user : ${users}">
    <tr>
        <td th:text="${user.login}">登录名</td>
        <td th:text="${user.name}">姓名</td>
    </tr>
    <tr>
        <td colspan="2" th:text="${user.address}">地址</td>
    </tr>
  </th:block>
</table>

这种方式符合 HTML 规范,避免在 <table> 中添加非法的 <div> 容器,作为原型静态预览时也非常完美。

典型场景:结合仅原型注释块(兼顾原型与规范)

th:block 与「仅原型注释块」结合,可实现:

  • 静态预览:注释块隐藏 th:block,模板是合法的 HTML(无额外标签),浏览器可正常渲染;
  • 动态处理:Thymeleaf 移除注释标记,激活 th:block 的遍历逻辑,生成正确的多行 <tr>
html
<table>
    <!--/*/ <th:block th:each="user : ${users}"> /*/-->
    <!-- 静态预览:注释块隐藏 th:block,tr 作为普通静态行显示 -->
    <tr>
        <td th:text="${user.login}">登录名</td>
        <td th:text="${user.name}">姓名</td>
    </tr>
    <tr>
        <td colspan="2" th:text="${user.address}">地址</td>
    </tr>
    <!--/*/ </th:block> /*/-->
</table>
  • 静态打开模板:th:block 被注释包裹,页面显示静态的 <tr> 行,表格结构合法且预览友好;
  • Thymeleaf 处理后:注释标记被移除,th:block 执行遍历,生成多组 <tr>,且 th:block 自身消失,最终 HTML 规范。

关键优势

解决的问题传统方式(用 div 包裹)th:block 方式
HTML 合法性非法(table 内不能有 div)合法(仅保留 tr,无额外标签)
静态原型预览布局错乱布局正常,原型友好
遍历多标签无法实现(div 会破坏表格)轻松实现,逻辑清晰

其他实用场景

  • 条件渲染多标签:用 th:block 承载 th:if,控制多个标签的显示/隐藏:
    html
    <!-- 仅当用户是管理员时,显示两行操作按钮 -->
    <th:block th:if="${user.isAdmin}">
      <button th:text="编辑">编辑</button>
      <button th:text="删除">删除</button>
    </th:block>
  • 批量定义局部变量:用 th:block 承载 th:with,为多个标签共享局部变量:
    html
    <th:block th:with="df=#{date.format}">
      <p>创建时间:<span th:text="${#calendars.format(createTime,df)}">...</span></p>
      <p>更新时间:<span th:text="${#calendars.format(updateTime,df)}">...</span></p>
    </th:block>

总结

  1. th:block 是纯属性容器,执行完属性后自身消失,仅保留内部内容,核心解决「多标签需共享 Thymeleaf 逻辑」的问题;
  2. 最核心的价值是:在不破坏 HTML 规范的前提下(如 table 内的 tr 遍历),实现多标签的遍历/条件渲染;
  3. 结合仅原型注释块使用时,可同时满足「静态原型合法预览」和「动态渲染逻辑正确」,是 Thymeleaf 布局的核心工具。