第 2-5 課:Thymeleaf 頁面佈局

頁面佈局就是對前端的頁面進行劃分區域,每個區域有不同的職責,佈局是爲了更好地重複利用前端代碼,避免大量重複性的勞動。在現有的前端系統中,頁面佈局成了前端開發最重要的工作之一,Thymeleaf 在設計之初對頁面佈局就有考慮,通過 Thymeleaf 的相關語法可以很容易地實現對前端頁面佈局。

快速入手

Spring Boot 2.0 將佈局單獨提取了出來,需要單獨引入依賴:thymeleaf-layout-dialect。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

首先定義一個代碼片段 copyright.html,放到 layout 目錄下:

<footer th:fragment="copyright"> 
&copy; 2018
</footer>

th:fragment 定義一個代碼片段,創建 index.html 在頁面任何地方引入:

<body>
    <div th:insert="layout/copyright :: copyright"></div>
    <div th:replace="layout/copyright :: copyright"></div>
</body>

th:insert 和 th:replace 區別,insert 只是加載,replace 是替換。

Thymeleaf 3.0 推薦使用 th:insert 替換 2.0 的 th:replace。

layout 是文件夾地址,fileName 是文件名,語法這樣寫 layout/fileName:htmlhead,其中,htmlhead 是指定義的代碼片段,如 th:fragment="htmlhead"。

創建一個 indexController,指向 index.html:

@RequestMapping("/index")
public String index() {
    return "index";
}

在瀏覽器中輸入網址,http://localhost:8080/index,可以看到以下信息:

© 2018
© 2018

可以看到兩條版權信息,說明兩種方式都可以引入版權頁面信息,這就是 Thymeleaf 最簡單的頁面佈局了。

Thymeleaf 的這種特性,可以讓我們在開發過程中避免寫很多重複的代碼,如果頁面有共同的頭部、尾部或者其他地方均可採用這種技術。

片段表達式

Thymeleaf 3.0 引入了一種新型的表達式,作爲一般 Thymeleaf 標準的語法表達式之一,它就是:片段表達式

它使用類似 ~{commons::footer} 的語法,作用在 th:insert 和 th:replace 的內部。使用片段表達式支持引入片段的同時傳參來構造目標頁面,大大提高了代碼複用的靈活度。接下來使用一個案例來介紹片段表達式的使用。

創建一個 base.html 基礎頁面,作爲後續其他頁面引入的模板。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common_header(title,links)">
    <title th:replace="${title}">comm title</title>

    <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/myapp.css}">
    <link rel="shortcut icon" th:href="@{/images/favicon.ico}">
    <script type="text/javascript" th:src="@{/js/myapp.js}"></script>

    <th:block th:replace="${links}" />
</head>
<body>

</body>
</html>

使用 th:fragment 創建了一段代碼片段,命名爲 common_header 並且支持傳入兩個參數 title 和 links,並且指明瞭在頁面中使用的位置:

  • <title th:replace="${title}">comm title</title> 在此位置插入傳入的 title;
  • <th:block th:replace="${links}" /> 在此位置插入傳入的 link,th:block 作爲頁面的自定義使用不會展示到頁面中。

接下來創建一個 fragment.html 頁面,來使用上面創建的 common_header 代碼片段。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="base :: common_header(~{::title},~{::link})">
    <title>Fragment - Page</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
    <link rel="stylesheet" th:href="@{/cs/fragment.css}">
</head>
<body>

</body>
</html>

在 fragment.html 的頁面中使用 th:replace 引入了 common_header 代碼片段,並且在頁面中添加了 title 和 link 作爲參數傳遞到 common_header 頁面中。

在 IndexController 中添加訪問入口:

@RequestMapping("/fragment")
public String fragment() {
    return "fragment";
}

重新啓動項目後,在瀏覽器中輸入網址,http://localhost:8080/fragment,右鍵單擊查看源代碼,可以看到以下信息:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Fragment - Page</title>

    <link rel="stylesheet" type="text/css" media="all" href="/css/myapp.css">
    <link rel="shortcut icon" href="/images/favicon.ico">
    <script type="text/javascript" src="/js/myapp.js"></script>

    <link rel="stylesheet" href="/css/bootstrap.min.css"><link rel="stylesheet" href="/cs/fragment.css">
</head>
<body>

</body>
</html>

說明 fragment.html 頁面已經引入了 base.html 頁面中的代碼片段,fragment.html 頁面中傳入的 title 和 link 已經成功地插入到了 base.html 頁面的代碼片段中。

這就是片段表達式最常用的使用方式之一,也是版本 3.0 針對頁面佈局推出的最新語法。因爲這一點,許多佈局(或頁面)技術在 Thymeleaf 3.0 中變得更容易使用。

頁面佈局

按照上面這個思路很容易做頁面佈局,按照常用的框架模式,將頁面分爲頭部、左側菜單欄、尾部和中間的展示區來做個示例:

在 templates/layout 目錄下新建 footer.html、header.html、left.html 頁面,內容如下。

footer.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>
    <title>footer</title>
</head>
<body>
<footer th:fragment="footer">
    <h1>我是 尾部</h1>
</footer>
</body>
</html>

header.html:

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>
    <title>header</title>
</head>
<body>
<header th:fragment="header">
    <h1>我是 頭部</h1>
</header>
</body>
</html>

left.html:

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>
    <title>left</title>
</head>
<body>
<left th:fragment="left">
    <h1>我是 左側</h1>
</left>
</body>
</html>

templates 目錄下新建 layout.html 頁面內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">
<head>
    <meta charset="UTF-8"></meta>
    <title>Layout</title>
</head>
<body>
    <div >
        <div th:replace="layout/header :: header"></div>
        <div th:replace="layout/left :: left"></div>
        <div layout:fragment="content" > content</div>
        <div th:replace="layout/footer :: footer"></div>
    </div>
</body>
</html>

引入佈局的語法命名空間:xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout",使用 th:replace 的語法將網站的頭部、尾部、左側引入到頁面中,同時定義了一個代碼片段 content,可以作爲後期頁面正文的替換內容。

後端添加訪問入口:

@RequestMapping("/layout")
public String layout() {
    return "layout";
}

啓動後訪問地址:http://localhost:8080/layout,可以看到頁面展示如下:

我是 頭部
我是 左側
content
我是 尾部

可以看出 layout.html 頁面已經成功地引入了頁面的頭部、尾部、左側。接下來以 layout.html 作爲一個頁面模板,任何頁面想使用此佈局時,只需要替換中間的 content 模塊即可,新建 home.html 來測試:

<html xmlns:th="http://www.thymeleaf.org"  xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout" layout:decorate="layout">
<head>
    <meta charset="UTF-8"></meta>
    <title>Home</title>
</head>
<body>
    <div layout:fragment="content" >
        <h2>個性化的內容</h2>
    </div>
</body>
</html>
  • <html>標籤中添加 layout:decorate="layout" 使用 layout.html 頁面的佈局。
  • <div layout:fragment="content" >替換 layout.html 頁面中的 content 代碼片段。
  • layout:decorator 標籤在 3.0 過期,推薦使用新的標籤 layout:decorate 進行頁面佈局。

Controller 添加訪問:

@RequestMapping("/home")
public String home() {
    return "home";
}

重啓後,在瀏覽器中輸入網址 http://localhost:8080/home,發現 home.html 頁面已經採用了 layout.html 的頁面佈局,content 部分的內容被替換爲:“個性化的內容”,展示內容如下:

我是 頭部
我是 左側
個性化的內容
我是 尾部

這樣其他頁面如果都是類似的結構都可以採用這樣的方式來使用。

採用頁面模板佈局的時候有兩個關鍵設置:

  • 在模板頁面定義需要替換的部分 layout:fragment="content";
  • 在需要引入模板的頁面頭部寫 layout:decorate="layout"",再修改 layout:fragment="content" 中的內容。

總結

通過本課的學習發現 Thymeleaf 對代碼片段重複利用、頁面佈局都有很好的支持,Thymeleaf 3.0 引入代碼片段語法更加方便佈局技術的使用。Thymeleaf 3.0 的頁面佈局技術,降低了後端開發人員學習頁面佈局的成本,使用頁面佈局技術後會高效地複用前端頁面,減少了開發量、穩定前端頁面結構。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章