Spring Boot 快速上手(8)Thymeleaf模板引擎基本使用
介绍
官网的介绍
译[Google翻译]
集成Thymeleaf
添加依赖
在Spring Boot 项目中添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
刷新maven
测试页面
新建 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
首页....
</body>
</html>
首页控制器IndexController
package org.example.mybatisplus.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* <h1></h1>
*
* @version 1.0
* @author: Vincent Vic
* @since: 2022/01/15
*/
@Controller
public class IndexController {
@GetMapping("/")
public String index(){
return "index";
}
}
基本使用
取值
创建商品信息网页goodInfo.html,其中使用头部添加 xmlns:th=“http://www/thymeleaf.org”,取值使用th:text标签
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品列表</title>
</head>
<body>
获取单个值:<label th:text="${str}"></label>
获取单个值浮点型:<label th:text="${price}"></label>
<hr/>
获取对象(商品信息)
<hr/>
id:<label th:text="${good.id}"></label>
名称:<label th:text="${good.goodName}"></label>
价格:<label th:text="${good.goodPrice}"></label>
<hr/>
</body>
</html>
编写控制器GoodController ,为了方便这里写死数据
通过Model的addAttribute添加传值信息,可以是单个字符串,浮点型,整形,浮点型,对象等,也可以是集合,键值对
package org.example.mybatisplus.demo.controller;
import org.example.mybatisplus.demo.entity.Good;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
/**
* <p>
* 商品表 前端控制器
* </p>
*
* @author by Vincent Vic
* @since 2022-01-14
*/
@Controller
@RequestMapping("/good")
public class GoodController {
@GetMapping("get/{id}")
public String getGood(@PathVariable("id")Integer id, Model model){
//添加字符串信息
model.addAttribute("str","这是字符串信息");
//添加浮点型
model.addAttribute("price",32.2);
//添加对象
Good good = new Good();
good.setId(id);
good.setGoodName("智能手机");
good.setGoodPrice(new BigDecimal("5000.00"));
model.addAttribute("good",good);
return "goodInfo";
}
}
其中使用到的Good实体类
package org.example.mybatisplus.demo.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 商品表
* </p>
*
* @author by Vincent Vic
* @since 2022-01-14
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Good implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 商品名称
*/
private String goodName;
/**
* 商品价格
*/
private BigDecimal goodPrice;
}
标签
th:text
<label th:text="${good.goodName}"></label>
<p th:text="${price}"></p>
<div th:text="${str}"></label>
th:inline 内联标签
HTML 内联
实现:商品名称:智能手机
<label th:text="${good.goodName}">商品名称:</label>
<!-- 如果这么写 这句代码会将标签中的内容覆盖 -->
商品名称: <label th:text="${good.goodName}"></label>
<!-- 这么写可以实现,但Thymeleaf提供了th:inline标签属性可以借助实现 -->
<label th:inline="text">商品名称:[[${good.goodName}]]</label>
样式内联
编写部分内容动态颜色,测试代码
<label class="style1">显示红色</label>
头部添加样式标签,获取控制器传递的color,控制器传递red参数,省略代码
<style type="text/css" th:inline="css">
.style1{
color: [[${color}]];
}
</style>
JavaScript内联
使用方法与样式内联一致
<script type="css/javascript" th:inline="javascript">
</script>
th:object 对象标签
th:object 获取对象,只要在div里面,都可以使用’*{}'直接获取对象属性的值
<div th:object="${good}">
id:<label th:text="*{id}"></label>
名称:<label th:text="*{goodName}"></label>
价格:<label th:text="*{goodPrice}"></label>
<hr/>
</div>
测试代码
在goodInfo.html基础上修改
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>商品列表</title>
<style type="text/css" th:inline="css">
.style1{
color: [[${color}]];
}
</style>
</head>
<body>
获取单个值:<label th:text="${str}"></label>
获取单个值浮点型:<label th:text="${price}"></label>
<hr/>
获取对象(商品信息)
<hr/>
id:<label th:text="${good.id}"></label>
名称:<label th:text="${good.goodName}"></label>
价格:<label th:text="${good.goodPrice}"></label>
<hr/>
HTML内联使用:<label th:inline="text">商品名称: [[${good.goodName}]]</label><br/>
样式内联使用:<label class="style1">显示红色</label>
<hr/>
th:object 属性使用
<div th:object="${good}">
id:<label th:text="*{id}"></label>
名称:<label th:text="*{goodName}"></label>
价格:<label th:text="*{goodPrice}"></label>
<hr/>
</div>
</body>
</html>
在控制器GoodController的getGood方法添加
//内联添加属性
//传递颜色
model.addAttribute("color","red");
流程控制
th:each 循环标签
使用th:each标签属性编写商品列表功能
控制器GoodController中添加方法
@GetMapping("list")
public String getGood(Model model){
List<Good> list = new ArrayList<>();
//生成模拟数据
for (int i = 1; i <= 10 ; i++) {
Good good = new Good();
good.setId(i);
good.setGoodName("智能手机 X"+i);
good.setGoodPrice(new BigDecimal("5"+(i%9)+"00.00"));
list.add(good);
}
model.addAttribute("goods",list);
return "goodList";
}
页面模板goodList.html
<table>
<caption>商品列表</caption>
<thead>
<tr>
<th>编号</th>
<th>商品名称</th>
<th>商品价格</th>
</tr>
</thead>
<tbody>
<tr th:each="good:${goods}">
<td th:text="${good.id}"></td>
<td th:text="${good.goodName}"></td>
<td th:text="${good.goodPrice}"></td>
</tr>
</tbody>
</table>
分支标签
th:if 判断标签
th:if 分支标签 如果条件不成立则不显示标签,成立则显示标签
在原有商品列表页面修改,添加了商品评估列,使用th:if 判断小于5500的显示精品推荐,反之显示价格偏高
<table>
<caption>商品列表</caption>
<thead>
<tr>
<th>编号</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品评估</th>
</tr>
</thead>
<tbody>
<tr th:each="good:${goods}">
<td th:text="${good.id}"></td>
<td th:text="${good.goodName}"></td>
<td th:text="${good.goodPrice}"></td>
<td th:if="${good.goodPrice} < 5500" style="color: aqua">精品推荐</td>
<td th:if="${good.goodPrice} >= 5500" style="color: #ff7700">价格偏高</td>
</tr>
</tbody>
</table>
th:switch 选择标签
th:switch和th:case配合使用
依旧在商品列表中修改,将价格取余会得到0,1,2,分别对应三种情况,仅为了内容形成三个条件用于测试
<table>
<caption>商品列表</caption>
<thead>
<tr>
<th>编号</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品评估</th>
</tr>
</thead>
<tbody>
<tr th:each="good:${goods}">
<td th:text="${good.id}"></td>
<td th:text="${good.goodName}"></td>
<td th:text="${good.goodPrice}"></td>
<!-- <td th:if="${good.goodPrice} < 5500" style="color: aqua">精品推荐</td>-->
<!-- <td th:if="${good.goodPrice} >= 5500" style="color: #ff7700">价格偏高</td>-->
<td th:switch="${good.goodPrice}%3">
<label th:case="0">精品推荐</label>
<label th:case="1">商品热卖</label>
<label th:case="2">销售榜单</label>
</td>
</tr>
</tbody>
</table>
碎片使用
在开发一个网站的时候,我们通常会是上中下结构,上下往往内容往往是一样的,只有内容部分是不一样的不同,Thymeleaf提供引入页面的功能,可以将一样的页面抽成一个单独的网页,在每个页面引用,如果修改引用的页面内容,全部引用的页面也会改变。
碎片定义
component/header.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>header</title>
</head>
<body>
<div th:fragment="header" style="background-color: aqua;color:white;width: 100%;height: 60px;">
头部
</div>
</body>
</html>
component/footer.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>footer</title>
</head>
<body>
<div th:fragment="footer" style="background-color: gainsboro;color:white;width: 100%;height: 60px;position: absolute;bottom: 0px;">
底部
</div>
</body>
</html>
引入
控制器IndexController添加跳转
@GetMapping("/a")
public String a(){
return "a";
}
@GetMapping("/b")
public String b(){
return "b";
}
th:include
编写a.html
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www/thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>a 页面</title>
</head>
<body>
<div th:include="component/header::header"></div>
<div>
内容 A
</div>
<div th:include="component/footer::footer"></div>
</body>
</html>
此时测试
页面没有显示任何样式,通过F12检查发现th:include并没有包含样式
<div>
头部
</div>
<div>
内容 A
</div>
<div>
底部
</div>
th:replace
将th:include修改为th:replace,重新运行,此时样式就有了