Skip to content

8.5 布局继承

Thymeleaf 中可以通过片段(fragment) 实现「布局继承」——将通用的页面布局(如头部、页脚、标题区域)封装为一个布局片段,业务页面只需传入自定义的标题、内容等参数,即可复用整个布局结构,无需重复编写公共代码。

html
<!DOCTYPE html>
<html th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">
<head>
    <!-- 标题区域:替换为传入的 title 片段 -->
    <title th:replace="${title}">Layout Title</title>
</head>
<body>
    <!-- 布局固定内容:所有页面共享 -->
    <h1>Layout H1</h1>
    <!-- 内容区域:替换为传入的 content 片段 -->
    <div th:replace="${content}">
        <p>Layout content</p>
    </div>
    <!-- 布局固定页脚:所有页面共享 -->
    <footer>
        Layout footer
    </footer>
</body>
</html>

示例用 th:fragment 定义名为 layout 的布局片段,接收 titlecontent 两个参数(类型为标记片段),作为布局中可自定义的部分:

通过 th:replace 调用布局片段,并传入自定义的标题和内容片段:

html
<!DOCTYPE html>
<!-- 替换整个 html 标签为布局片段,传入 title 和 section 作为参数 -->
<html th:replace="~{layoutFile :: layout(~{::title}, ~{::section})}">
<head>
    <!-- 自定义标题:作为 title 参数传入布局 -->
    <title>Page Title</title>
</head>
<body>
<!-- 自定义内容:作为 content 参数传入布局 -->
<section>
    <p>Page content</p>
    <div>Included on page</div>
</section>
</body>
</html>

页面中的 <html> 标签会被布局片段完全替换,同时布局中的 titlecontent 占位符会被业务页面的自定义内容替换。

如有需要,布局可以由多个片段构成,例如页眉和页脚。

核心规则与扩展

(1)布局的拆分与组合

布局片段不仅可以是整体的 <html> 标签,也可以拆分为多个小片段(如 headerfootercontent),灵活组合:

html
<!-- 拆分后的布局文件 layoutFile.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!-- 头部片段 -->
<header th:fragment="header(title)">
    <title th:text="${title}">Default Title</title>
    <link rel="stylesheet" th:href="@{/css/common.css}">
</header>
<!-- 页脚片段 -->
<footer th:fragment="footer">
    <p>© 2026 My App</p>
</footer>
<!-- 整体布局片段:组合多个小片段 -->
<div th:fragment="layout(title, content)">
    <th:block th:replace="::header(${title})" />
    <div th:replace="${content}">Default Content</div>
    <th:block th:replace="::footer" />
</div>
</html>
(2)简化写法

可省略片段表达式的 ~{} 包裹符,让代码更简洁:

html
<!-- 简化后的业务页面调用 -->
<html th:replace="layoutFile :: layout(::title, ::section)">
<head>
    <title>Page Title</title>
</head>
<body>
<section>
    <p>Page content</p>
</section>
</body>
</html>
(3)默认值处理

如果业务页面未传入某个参数,可通过「无操作令牌 _」保留布局的默认内容:

html
<!-- 仅传入 content,title 保留布局默认值 -->
<html th:replace="layoutFile :: layout(_, ::section)">
<head>
    <title>Page Title</title> <!-- 该标题不会生效,布局保留默认 Layout Title -->
</head>
<body>
<section>
    <p>Page content</p>
</section>
</body>
</html>

布局继承的核心价值

  • 复用性:公共布局(如头部、页脚、样式/脚本引入)只需写一次,所有页面继承即可;
  • 一致性:保证所有页面的布局结构统一,避免样式/结构不一致;
  • 灵活性:业务页面只需关注自定义内容,无需关心布局细节,降低维护成本。

总结

  1. 布局继承的核心是「通用布局片段 + 业务页面传参」:布局片段封装固定结构,业务页面传入自定义标记片段;
  2. 通过 th:fragment 定义布局参数,th:replace 调用布局并传递自定义内容;
  3. 支持布局拆分(多个小片段组合)、默认值保留(无操作令牌 _)等扩展用法,兼顾复用性和灵活性。