Thymeleaf使用入门

依赖


  • Maven
        Thymeleaf基础依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        
        layout布局依赖
        <dependency>
            <groupId>nz.net.ultraq.thymeleaf</groupId>
            <artifactId>thymeleaf-layout-dialect</artifactId>
            <version>2.3.0</version>
        </dependency>
  • Gradle
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.3.0'
}

thymeleaf方言


  • 以th开头的方式,需要在html标签里引入thymeleaf的命名空间:<html xmlns:th="http://www.thymeleaf.org">
    <span th:text="...">
  • 以data作为前缀,是html5里标准的用于自定义属性的,不需要引入命名空间
    <span data-th-text="...">

表达式


  • 变量表达式:${...}

<span th:text="${data.name}">

  • 消息表达式:#{...}

也称之为文本外部化、国际化或i18n,从国际化配置文件里去取key对应的值?不太懂

<table>
       <th th:text="#{header.address.city}">...</th>
</table>
  • 选择表达式:*{...}

经常与 th:object 替换对象配合使用,th:object="${book}"首先获取到对象book,"*{}"对象里取属性。
等于变量表达式${book.title},区别是${book}从整个上下文中取的,*{title}是从 ${book}中取的,执行效率更高。

<div th:object="${book}">
        <span th:text="*{title}">...</span>
</div>
  • 链接表达式:@{...}
    绝对链接:<a th:href="@{http://www.baidu.com/main}">...</a>
    协议相对链接:<a th:href="@{//static/html/initial}">...</a>
    服务器相对链接:<a th:href="@{~/contents/main}">...</a>
    目录相对链接:<a th:href="@{../docments/report}">...</a>

  • 分段表达式:th:insert、th:replace、th:include(3.0以后不推荐)

被替换的内容:

<footer th:fragment="copy">
        <a href="https://www.baidu.com">2019 蟹蟹<a/>
</footer>

执行替换的部分:

<body>
        <div th:insert="footer::copy"></div>
        <div th:replace="footer::copy"></div>
        <div th:include="footer::copy"></div>
</body>

替换效果:

<body>
        // 1、insert
        <div>
            <footer th:fragment="copy">
                <a href="https://www.baidu.com">2019 蟹蟹<a/>
            </footer>    
        </div>

        // 2、replace
        <footer>
            <a href="https://www.baidu.com">2019 蟹蟹<a/>
         </footer>

        // 3、include
        <div>
            <a href="https://www.baidu.com">2019 蟹蟹<a/>
        </div>
</body>

文本替换

  • 文本:' ' 单引号引起来表示是文本内容
  • 数字:不需要单引号,也支持一些数学计算
<span th:text=" '这是要展示的文本' ">这里的部分会被替换掉</span>
<span th:text=" 1+1 ">这里的部分会被替换掉</span>

属性赋值

th:value
<input th:value = "${user.name}" />

迭代器:th:each

<li th:each="book:${books} th:text="${book.title}"><li>

状态变量:
index:迭代器索引从0开始
count:迭代器索引从1开始
size:迭代器大小
current:当前迭代器值
even/odd:当前索引是偶数/奇数
first/last:第一个/最后一个

  • select下拉框数据回显
        <select id="gysxz" onchange="getGysbm(this.value)">
            <option th:each="gys:${gysList}"  th:value="${gys.gysbm}" th:text="${gys.gysmc}"  th:selected="${gys.gysmc}"></option>
            <option selected>--请选择供应商--</option>
        </select>
    function getGysbm() {
        var option=$("#gysxz option:selected").val();
        console.log("选中的值是:"+option);
    }

内联表达式


[[...]] 和 [(...)] 分别对应于 th:text 和 th:utext,前者会对特殊字符进行转义,后者不会对特殊字符转义

激活内联使用th:inline 属性,它有四个模式:text、javascript、css 和 none。

  • 文本内联:
    <p th:text="${value}"></p> 等同于:<p th:inline="text">[[${value}]]</p>

  • JavaScript内联:

<javascript th:inline="javascript">
    alert([[${value}]]);
</script>
  • CSS内联:
变量:
classname = 'main elems'
align = 'center
内联写法:
<style th:inline="css">
    .[[${classname}]]{
        text-align:[[${align}]];
    }
</style>
转换成这样:
<style th:inline="css">
    .main\ elems {
        text-align: center;
    }
</style>
  • 禁用内联:th:inline=none
    <p th:inline="none">A double array looks like this:[[1,2,3],[4,5]]!</p>

  • 其它th:标签
    th:value 属性赋值 <input th:value = "${user.name}" />

页面布局 一


  • 通用模板页面
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>公用模板</title>
</head>
<body>
    <h1>页头</h1>
    <div layout:fragment="content">等待被替换</div>
    <h1>页尾</h1>
</body>
</html>
  • 标题子页面有则显示子页面的,子页面没有则显示父页面的。
  • 子页面 head和body标签并不是必须的。
  • 自定义内容页面
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorate="base">
<!--<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{base.html}">-->
<head>
    <meta charset="UTF-8">
    <title>新标题</title>
</head>
<body>

<div layout:fragment="content">已经被替换的内容</div>

</body>
</html
image.png

页面布局 二


  • 在template文件夹新建fragments模板存放文件夹,在里面新建header.htmlfooter.html两个模板文件
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div th:fragment="header">
        <h1>Thymeleaf in action</h1>
        <a href="/users">首页</a>
    </div>
</body>
</html>



<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div th:fragment="footer">
        <a href="https://www.baidu.com">百度地址连接</a>
    </div>
</body>
</html>
  • 新建首页list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<dvi th:replace="~{fragments/header::header}"></dvi>
<h1>我是中间的内容!</h1>
<dvi th:replace="~{fragments/footer::footer}"></dvi>
</body>
</html>
image.png

公共页面数据传递


  • 新建全局控制器,用于返回公共页面的数据
/*
@ControllerAdvice的使用场景
1、全局异常处理
2、全局数据绑定:在每一个 Controller 的接口中,都能够访问到这些数据
3、全局数据预处理
*/

/*
使用 @ModelAttribute 注解标记该方法的返回数据是一个全局数据,
默认情况下,这个全局数据的 key 就是返回的变量名,value 就是方法返回值
也可以通过 @ModelAttribute 注解的 name 属性去重新指定 key。
*/
@ControllerAdvice
@ResponseBody
public class globalController {

    @ModelAttribute(name="datas")
    public ArrayList<String> returnDatas() {
        ArrayList<String> list = new ArrayList<>();

        list.add("新闻");
        list.add("军事");
        list.add("游戏");

        return list;
    }
}
image.png
image.png

其它

  • 获取ModeAndView传来的数据
<script th:inline="javascript"> // 需要添加 th:inline 才能访问 model 中的属性
    window.onload = function () {
        console.log("页面加载完成");
        // 获取ModelAndView中的dbgoods对象
        var dbgoods = [[${dbgoods}]];
        // 打印
        console.log(dbgoods);
    }
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容