个人感觉thymeleaf并不好用(2019年7月)
- 尽管可以自定义标签 但依然没有jsp自定义标签方便 点击查看自定义标签
- 而thymeleaf所谓的可单独打开也只是噱头 引入的js css直接访问路径和web路径大多数时候并不相同
- 性能也是最慢的 静态模板速度最快的是velocity(号称比jsp快) 所以如果使用thymeleaf让前后端分离 为什么不使用webpack + vue呢
- 现在个人经验感觉还是jsp强大 可以直接对任意html片段进行限制 直接使用java类 直接写java代码
- 综上所述thymeleaf现在还不太适合web开发 但公司技术选型也很无奈?
thymeleaf springboot默认使用的静态模板 看完本文大概15分钟
引用命名空间<html xmlns:th="http://www.thymeleaf.org">
thymeleaf无数据时input标签必须’/'结尾 不可以操作没有的数据 可通过修改配置文件解决
#解析非严格的html5 标签不闭合也可使用 默认thymeleaf配置为HTML5
spring.thymeleaf.mode=LEGACYHTML5
逻辑运算符’>’ ‘<’ ‘<=’ ‘>=’ ‘==’ ‘!=‘可正常使用 而使用’<’ '>'时需要使用对应的html转义符 >
<
使用对象名.属性名 或 对象名[‘属性名’] 的方式取值可直接获取值
判断实体是否为空 但最好还是使用如下方法
<input type="text" th:value="${user?.info}">
<input type="text" th:value="${one?.two?.three}">
<input type="text" th:value="${user!=null?user.info:''}">
<input type="text" th:value="${user?.info}">
<span th:text="${user}?:'默认值'">span>
后台springmvc 使用model传入数据
@Controller
public class TestController {
@ResquestMapping("test")
public String testModel(Model model){
List<User> userList = userService.findAll();
User user = userService.findOne();
model.addAttribute("user", userList);
return "admin/userList"
}
}
${}用法 变量表达式 访问页面上下文变量 配合th标签使用 功能同jstl中${}
<input type="text" th:value="${user}"/>
有值时浏览器显示<input type="text" value="test">
无值时浏览器显示<input type="text" value/>
<input type="text" th:text="${msg}"/>
有值时<input type="text" value=">h1≶文本>h1≶"/>
无值时<input type="text" th:text="${msg}"/>
<span th:utext="${msg}"><span>
<span><h1>文本h1><span>
另类取值方式
<input type="text" th:text="${user.getName()}"/>
<input type="text" th:text="${user.name}"/>
<input type="text" th:text="${user['name']}"/>
字符串替换
<span th:text="'Welcome' + ${user.name} + '!'">span>
<span th:text="|Welcome${user.name}!|">span>
<span>Welcome李磊span>
获取当前url上的参数
<span th:text="${param.id}">span>
保存属性值中的引号
<button th:onclick="|location.href='/user/form?id=${user.id}';|">修改button>
<button onclick="location.href='/user/form?id=1';">修改button>
<input th:value="${'Welcome'''+user.name+''''}"/>
<a th:href="${'javascript:location.replace(''/word/form?id='+file.id+''');'}">a>
<button th:onclick="${'location.href=''/video/form?id='+video.id+''''}">编辑button>
<input th:value="Welcome'李磊'"/>
<a th:href="javascript:location.replace('/word/form?id=1');">a>
<button onclick="location.href='/video/form?id=1'">编辑button>
注意 字符串必须包含再${}中 错误示范如下
<a th:href="'javascript:location.replace(''/word/form?id='+${file.id}+''');'">a>
thymeleaf注释
thymeleaf解析时会先移除代码再解析页面
info为不存在的属性但并不会报错 staff为不存在的值解析正常
<p th:text="user.info">多行注释p>
<p th:text="staff">多行注释p>
info为不存在的属性但并不会报错 staff为不存在的值解析正常
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
原型注释 thymeleaf解析时会先移除表达式保留结构再解析页面
info为不存在的属性 此时会抛出org.attoparser.ParseException
staff为不存在的值 解析正常
如下为正常解析结果
结果如下
<div inner="text">
fileName-lilei
<p>fileNamep>
<p>文本p>
div>
----- ----- ----- ----- -----
结果如下
<div>fileNamediv>
th:attr用法
添加单个属性
th:attr="class=btn"
添加多个属性
th:attr="class=btn,title=普通按钮"
单个属性多个值
th:attr="class=|btn btn-dark|"
属性值动态赋值
th:attr="value=#{user.name},title=#{user.info}"
属性值动态拼接
th:attr="value=user_|#{user.id}|"
属性值中有引号
th:attr="value=|{test:'#user.info'}|"
src为''时 src属性会消失
th:attr="src=${user==null?'':'user.jpg')}"
在js中使用thymeleaf表达式获取数据
<script type="text/javascript" th:inline="JavaScript">
//
var user = [[${user}]]//json对象
//]]>
script>
*{}用法 取值表达式 语法糖
<div th:object="${userList[0]}" >
<span th:text="*{name}">span><br>
<span th:text="*{info}">span><br>
div>
@{}用法 @{}相当于jsp如下用法
<% String path = request.getContextPath();
String basePath = request.getScheme()+"://"
+request.getServerName()+":"request.getServerPort()+path+"/";
%>
${pageContext.request.getContextPath()}
<img th:src="@{/resource/imgage/test.jpg}"/>
<a th:href="@{/user/findAll}">查询所有a>
<a attr="href=${/user/findAll}">查询所有a>
@{} 传参
<a th:href="@{/user/findAll(id=${user?.id}, userName='userName')}">buttona>
三元运算符用法 两种写法
<td th:text="${user.sex==1?'男':'女'}">td>
<td th:text="${user.sex}==1?'男':'女'">td>
th:if用法 流程控制
<span th:if="${userList!=null}">
<span th:text="${user.name}">span>
<span th:if="${user.name} eq 'one'">相同span>
<span th:if="${user.name} ne 'two'">不相同span>
<span th:text="${user.name}?:'默认值'">span>
span>
th:unless th:if判断取反
<span th:unless="${userList==null}">
<span th:text="${user.name}">span>
span>
th:switch th:case 分支判断
<div th:switch="${user.age}">
<p th:case="18">18岁p>
<p th:case="16">16岁p>
<p th:case="*">默认值p>
div>
foreach用法 遍历循环
thymeleaf会自动生成一个变量名+'Stat'的状态变量
<tr th:each="user:${userList}">
<td th:text="${userStat.index}">td>
<td th:text="${user.name}">td>
tr>
当然可以手动声明状态变量
<tr th:each="user,test:${userList}">
<td th:text="${test.index}">td>
<td th:text="${user.name}">td>
tr>
从0开始 索引属性index
从1开始 统计属性count
大小属性 size
等同于当前元素 current
索引是否为奇数 odd
索引是否为偶数 even
当前元素是否为第一个元素 first
当前元素是否为最后一个元素 last
/**
* @Auther: 李磊
* @Date: 2019/3/23 11:00
*/
@Controller
@RequestMapping("/Test")
public class TestController {
@RequestMapping("/test")
public String test(Model model){
List list = new ArrayList();
for (int i=0;i<10;i++) {
list.add("第"+i+"元素");
}
model.addAttribute("list",list);
return "index";
}
}
<table>
<tr th:each="user:${list}">
<td th:text="${user}">td>
<td th:text="${userStat.count}"/>
<td th:text="${userStat.size}"/>
<td th:text="${userStat.current}"/>
<td th:text="${userStat.first}"/>
<td th:text="${userStat.last}"/>
<td th:text="${userStat.even}"/>
<td th:text="${userStat.odd}"/>
<td th:text="${userStat.index}"/>
<td th:if="${userStat.current==user}">successtd>
tr>
table>
浏览器显示
第0元素 1 10 第0元素 true false false true 0 success
第1元素 2 10 第1元素 false false true false 1 success
第2元素 3 10 第2元素 false false false true 2 success
第3元素 4 10 第3元素 false false true false 3 success
第4元素 5 10 第4元素 false false false true 4 success
第5元素 6 10 第5元素 false false true false 5 success
第6元素 7 10 第6元素 false false false true 6 success
第7元素 8 10 第7元素 false false true false 7 success
第8元素 9 10 第8元素 false false false true 8 success
第9元素 10 10 第9元素 false true true false 9 success
#{} 消息表达式或内置对象 读取properties文件 国际化
file_name.properties
one = message1
two = message2
在application.properties中添加
spring.messages.basename=file_name
html中使用
<span th:value="#{one}">span>
<span th:inline="text">[[#{two}]]span>
内置对象 详细用法见官网
日期格式化
<span th:inner="text">
[[${#dates.format(new java.util.Date().getTime(), 'yyyy-MM-dd hh:mm:ss')}]]
[[${#dates.createNow()}]]
[[${#dates.createToday()}]]
span>
字符串处理
<span th:inner="text">
[[${#strings.isEmpty(user.name)}]]
[[${#strings.startsWith(name,'one')}]]
[[${#strings.endsWith(name,endingFragment)}]]
[[${#strings.length(str)}]]
[[${#strings.equals(str)}]]
<span>
httpServletRequest
${#httpServletRequest.getAttribute('user')}
${#httpServletRequest.getParameter('info')}
${#httpServletRequest.getContextPath()}
${#httpServletRequest.getRequestName()}
httpSession
${#httpSession.getAttribute('user')}
...
在js中使用thymeleaf表达式
<script th:inline="javascript">
/*
var name = [[${user.name}]];
//当无thymeleaf数据时默认值为'lilei' 有数据时会自动解析/*[[ ]]*/的表达式
var name = /*[[${user.name}]]*/ 'lilei';
/*]]>*/
script>
<span th:text="${user.name}">span>
<span th:inline="text">
Welcome : <span>[[${user.name}]]span>
span>
中文乱码 修改IDE的文件编码
th:with 定义布局变量
<span th:with="name=${user.name}">
username : <span th:text="${name}">span>
span>
<span th:with="name=${user.name},info=${user.info}">
username : <span th:text="${name}">span>
userninfo : <span th:text="${info}">span>
span>
th:selected 下拉框默认选中
<select>
<option th:selected="${sex=='0'}" value="0">男option>
<option th:selected="${sex=='1'}" value="1">女option>
<option th:selected="${sex=='x'}?'selected':''" value="x">xoption>
select>
th:include 抽取通用代码
<span th:fragment="testPage">
<p>This is the test pagep>
span>
<span th:replace="page/test::testPage">span>
<span th:replace="page/test.html::testPage">span>
<span th:replace="::testPage">span>
<span th:replace="page/test::">span>
<span th:include="page/test::(${user.power=10}?'admin':'staff')">span>
th:include传参
<div th:fragment="test(one, two, three)">
<p th:text="'>>> ' + ${one} + ' <<<'">p>
<p th:text="'>>> ' + ${two} + ' <<<'">p>
<p th:text="'>>> ' + ${three} + ' <<<'">p>
div>
<div th:include="page/test :: test(
one=${status} == true ? 'yes' : 'no'
, two = 'two'
, '测试'
)">
div>
th:insert和th:include与th:replace作用一致 细微区别如下
th:insert 保留自己的主标签 保留th:fragment的主标签
th:replace 舍弃自己的主标签 保留th:fragment的主标签
th:include 保留自己的主标签 舍弃th:fragment的主标签
如需两者标签都不保存可使用th:block配合
th:block标签
<th:block th:each="video : ${videos}">
<div th:text="${video.video_name} + '-lilei'">div>
th:block>
<div>fileName1-lileidiv>
<div>fileName2-lileidiv>
<div>fileName3-lileidiv>
----- ----- ----- ----- -----
<th:block th:each="video : ${videos}">
<p th:text="${video}">p>
th:block>
<p>fileName1p>
<p>fileName2p>
<p>fileName3p>