HTMX 是一個小型 JavaScript 庫,可讓您使用 HTML 中的自定義屬性來定義頁面中元素的行為。它有點像現代版的 onclick 屬性,但功能更強大、更靈活。
它的效率也更高,因為它使用瀏覽器內建的 HTTP 協議棧來發出請求,而且可以使用瀏覽器內建的快取和歷史記錄管理功能。
它非常適合 Spring Boot 等伺服器端框架,因為它允許使用伺服器來生成頁面的內容和行為,並允許使用瀏覽器的內建功能來管理導航和歷史記錄。
HTMX安裝
1、最簡單的方法是從 CDN 抓取,然後新增到 layout.html 模板中:
<script src='https://unpkg.com/htmx.org/dist/htmx.min.js'></script>
2、使用 Webjar 將庫載入到 classpath 中,這樣也可以正常工作。Spring 可以做一些額外的事情來幫助瀏覽器快取程式庫,還可以幫助進行版本管理。見:GitHub (dsyer/webmvc-thymeleaf).
表單處理
我們可以輕鬆新增的一項功能是使用 HTMX 提交表單,而無需重新載入整個頁面。為此,我們可以在表單元素中新增 hx-post 屬性:
<form th:action=<font>"@{/greet}" method="post" hx-post="/greet"> |
這將導致 HTMX 攔截表單上的提交操作,並使用 AJAX 請求將資料傳送到伺服器。伺服器將處理請求並返回結果,HTMX 將用結果替換表單內容。
如果不希望結果替換表單內容的效果,可以透過在表單元素中新增 hx-target 屬性來解決這個問題:
<form th:action=<font>"@{/greet}" th:hx-post="@{/greet}" method="post" hx-target="content"> |
"conent"元素:包含ID 和 hx-swap-oob 屬性,以實現將傳入的內容應替換現有內容:
<div id=<font>"content" class="col-md-12" hx-swap-oob="true"> |
這樣,HTMX 就提取 "content "元素併為我們切換其內容。圖片和其他靜態內容不會重新載入,瀏覽器的歷史記錄也會更新,以反映頁面的新狀態。
後端springboot程式碼:
@PostMapping(path = <font>"/greet") |
HTMX 在向後端伺服器/greet發出的請求中新增了 hx-request 標頭:這是 HTMX 的一項功能,可讓您在伺服器端程式碼中匹配請求,接下來我們將使用該功能。
使用片段模板
現在,伺服器仍會為表單提交重新渲染整個頁面,可以透過使用片段模板來提高效率。
在 greet.html 模板中新增 th:fragment 屬性:
<div id=<font>"content" th:fragment="content" class="col-md-12" hx-swap-oob="true"> |
然後,我們就可以在 SampleController 中的一個新對映方法中使用該片段,該方法僅在請求來自 HTMX 時觸發(透過匹配 hx-request 頭資訊):
@PostMapping(path = <font>"/greet", headers = "hx-request=true") |
(":: "語法是 Thymeleaf 的一項功能,可讓您呈現模板的片段。例如,找到 "greet "模板,然後查詢名為 "content "的片段)。
如果現在提交表單,並檢視瀏覽器開發工具中的網路活動,就會發現伺服器只返回了更新內容所需的頁面片段。
懶載入
另一種常見用例是在頁面首次載入時從伺服器載入內容,甚至可以根據使用者的偏好進行定製。
我們可以使用 HTMX 來實現這一功能,方法是在要觸發請求的元素上新增 hx-get 屬性。
我們可以在 layout.html 模板中嘗試使用徽標,而不是靜態地包含圖片。
下面是靜態包含圖片:
<div class=<font>"row"> |
上述程式碼替換為:
<div class=<font>"row"> |
上述程式碼使用了佔位符替換img位置
讓 HTMX 動態載入:
<div class=<font>"row"> |
注意:這裡新增了 hx-get 和 hx-trigger。
- hx-get 屬性告訴 HTMX 向伺服器發出 GET 請求,以獲取元素的內容。
- hx-trigger 屬性告訴 HTMX 在頁面載入時觸發請求。預設情況下是在點選時觸發。
因此,我們需要在 SampleController 中建立一個新的對映:
@GetMapping(path = <font>"/logo") |
為了只渲染 layout.html 模板中包含圖片的片段,必須再次修改 layout.html 模板,使用 th:fragment 屬性,替換hx-get和hx-trigger 屬性:
<div class=<font>"row" th:remove="all"> |
請注意,我們必須從模板中th:remove該片段,因為佔位符將在初始呈現時替換它。
如果現在執行應用程式,就會看到頁面載入時,旋轉圖示就被真實後端的logo圖片取代。
Spring Boot HTMX其他庫包
HTMX 還有更多的功能,我們沒有時間在此詳細介紹。值得一提的是,有一個 Java 庫可以幫助實現這些功能,而且還有一些 Thymeleaf 工具:Wim Deblauwe 編寫的 Spring Boot HTMX ,可作為 Maven Central 的依賴項。它可以透過自定義註解進行 hx-request 頭匹配,還能幫助實現 HTMX 的其他功能。
Unpoly庫包
Unpoly的CDN連結是:
<script src='https://unpkg.com/unpoly/unpoly.min.js'></script>
示例程式碼中的“unpoly”分支和以前一樣使用 Webjar。基本(整個頁面呈現)表單提交示例如下所示:
<div class=<font>"col-md-12"> |
hx-target變成了up-target,其餘的 HTMX 裝飾只是 Unpoly 中的預設設定。
要轉換為片段模板,我們需要遵循 HTMX 中的模式:新增一個th:fragment與 Unpoly 中的唯一標頭匹配的控制器方法,例如X-Up-Context。
Hotwired Turbo庫包
Hotwired Turbo 的 CDN 連結是:
<script src='https://unpkg.com/@hotwired/turbo/dist/turbo.es2017-umd.js'></script>
示例程式碼中的“turbo”分支和以前一樣使用 Webjar。基本表單提交示例如下所示:
<turbo-frame id=<font>"content"> |
Turbo 使用自定義元素 ( turbo-frame) 來標識要替換的內容,而不是標識表單處理互動的自定義屬性。表格的其餘部分不變。
要轉換為片段模板,我們需要th:fragment向<turbo-frame>和控制器方法新增一個宣告,以匹配來自 Turbo 的唯一標頭,例如Turbo-Frame。