
01-Thymeleaf
依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
首次访问页面
非常的简单,springBoot天生和thymeleaf整合的很紧密,只需要在src/main/resources/templates/
目录下创建index.html
,然后创建controller就好了,什么都不需要配置
java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String index() {
return "index"; // 返回模板名,无需.html后缀
}
}
代码抽离
比如我们想把头部信息给抽离出来,以便其他页面使用。
其实很简单,记住,
th:fragment 是定义一个代码片段,nav是代码片段的名字,也可以说成方法 (activePage) 是参数
1、首先,在src/main/resources/templates/component/
目录下创建一个新的HTML文件,例如head.html
。这个文件将包含你的导航栏代码。
如果你想让某些页面的导航栏略有不同(例如,当前页面对应的导航项有“active”类),可以通过传递参数给片段或者通过CSS/JavaScript动态处理。
例如,head.html
以接受一个activePage参数,并根据这个参数添加active类:
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="nav(activePage)">
<ul>
<li th:class="${activePage == 'home' ? 'active' : ''}">
<a href="/" th:href="@{/}">首页</a>
</li>
<li th:class="${activePage == 'about' ? 'active' : ''}">
<a href="/about" th:href="@{/about}">关于我们</a>
</li>
</ul>
</div>
</body>
</html>
2、在其他页面中引入导航栏片段
接下来,在你想要显示导航栏的任何页面中使用Thymeleaf的th:insert
或th:replace
属性来包含这个导航栏片段。例如,在index.html中:
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>首页</title>
</head>
<body>
<!-- 插入导航栏 -->
<div th:insert="~{component/head :: nav('home') }"></div>
<h1>欢迎来到首页</h1>
<!-- 页面主体内容 -->
</body>
</html>
渲染数据
渲染集合
java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;
@Controller
public class ListController {
@GetMapping("/items")
public String showItems(Model model) {
List<CategoryDO> list = categoryService.list();
model.addAttribute("items", items);
return "items"; // 返回模板名,无需.html后缀
}
}
渲染
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<table class="layui-table">
<thead>
<tr>
<th>类目名称</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
<tr th:each="item : ${items}">
<td th:text="${item.name}"></td>
<td th:text="${item.createTime}"></td>
<td> <button th:onclick="|edit(${item.id})|">编辑</button></td>
</tr>
</tbody>
</table>
</html>
动态加载JS文件
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>My Page</title>
<!-- 动态加载JS文件 -->
<script th:src="@{/static/js/utils/url.js(v=${version})}"></script>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>
动态渲染class样式
html
<!--假设你有一个布尔值active在你的模型中,用于决定是否应用一个名为active的CSS类:-->
<div th:class="${active} ? 'active' : 'inactive'">内容</div>
<div th:class="${code == 'sku'} ? 'active' : 'inactive'">内容</div>
<!--如果你想在已有的class基础上追加额外的类(而不是完全替换它们),可以使用th:classappend-->
<div class="default-class" th:classappend="${active} ? 'active' : ''">内容</div>
if-else渲染
通过组合 th:if
和 th:unless
实现互斥条件:
html
<!-- 用户已登录 -->
<div th:if="${user != null}">
欢迎,<span th:text="${user.name}"></span>!
</div>
<!-- 用户未登录 -->
<div th:unless="${user != null}">
<a href="/login">请登录</a>
</div>
使用 th:switch
实现多条件分支
html
<div th:switch="${user.role}">
<span th:case="'admin'" class="admin-menu">管理员菜单</span>
<span th:case="'user'" class="user-menu">用户菜单</span>
<span th:case="*" class="guest-menu">访客菜单</span>
</div>
三元表达式
html
<!-- 如果 message 不为空则显示 message,否则显示默认文本 -->
<span th:text="${show} ? '你好' : '暂无消息'"></span>
在 th:if
中直接使用逻辑运算符(and/or/not):
html
<div th:if="${user.active and user.role == 'admin'}">
用户是活跃管理员时显示
</div>
<div th:if="${not #strings.isEmpty(user.comment)}">
用户评论不为空时显示
</div>
绑定onclick
html
<button th:onclick="|edit(${item.id})|">编辑</button>
生成模版文件
java
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@Controller
public class ExampleController {
private final TemplateEngine templateEngine;
public ExampleController(TemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}
@GetMapping("/generateFile")
public ResponseEntity<ByteArrayResource> generateFile() throws IOException {
Context context = new Context();
context.setVariable("title", "Thymeleaf Example");
context.setVariable("message", "This is a message from the controller.");
String htmlContent = templateEngine.process("example", context);
// 将 HTML 内容转为字节数组
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.write(htmlContent.getBytes());
ByteArrayResource resource = new ByteArrayResource(outputStream.toByteArray());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=example.html")
.contentType(MediaType.TEXT_HTML)
.body(resource);
}
}
在 src/main/resources/templates
目录下创建一个 Thymeleaf 模板文件,例如 example.html
html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>My Example</title>
</head>
<body>
<h1 th:text="${title}">Default Title</h1>
<p th:text="${message}">Default message</p >
</body>
</html>