SpringBoo+HTMX编程简介
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="@{/greet}" method="post" hx-post="/greet"> |
这将导致 HTMX 拦截表单上的提交操作,并使用 AJAX 请求将数据发送到服务器。服务器将处理请求并返回结果,HTMX 将用结果替换表单内容。
如果不希望结果替换表单内容的效果,可以通过在表单元素中添加 hx-target 属性来解决这个问题:
<form th:action="@{/greet}" th:hx-post="@{/greet}" method="post" hx-target="content"> |
"conent"元素:包含ID 和 hx-swap-oob 属性,以实现将传入的内容应替换现有内容:
<div id="content" class="col-md-12" hx-swap-oob="true"> |
这样,HTMX 就提取 "content "元素并为我们切换其内容。图片和其他静态内容不会重新加载,浏览器的历史记录也会更新,以反映页面的新状态。
后端springboot代码:
@PostMapping(path = "/greet") |
HTMX 在向后端服务器/greet发出的请求中添加了 hx-request 标头:这是 HTMX 的一项功能,可让您在服务器端代码中匹配请求,接下来我们将使用该功能。
使用片段模板
现在,服务器仍会为表单提交重新渲染整个页面,可以通过使用片段模板来提高效率。
在 greet.html 模板中添加 th:fragment 属性:
<div id="content" th:fragment="content" class="col-md-12" hx-swap-oob="true"> |
然后,我们就可以在 SampleController 中的一个新映射方法中使用该片段,该方法仅在请求来自 HTMX 时触发(通过匹配 hx-request 头信息):
@PostMapping(path = "/greet", headers = "hx-request=true") |
(":: "语法是 Thymeleaf 的一项功能,可让您呈现模板的片段。例如,找到 "greet "模板,然后查找名为 "content "的片段)。
如果现在提交表单,并查看浏览器开发工具中的网络活动,就会发现服务器只返回了更新内容所需的页面片段。
懒加载
另一种常见用例是在页面首次加载时从服务器加载内容,甚至可以根据用户的偏好进行定制。
我们可以使用 HTMX 来实现这一功能,方法是在要触发请求的元素上添加 hx-get 属性。
我们可以在 layout.html 模板中尝试使用徽标,而不是静态地包含图片。
下面是静态包含图片:
<div class="row"> |
上述代码替换为:
<div class="row"> |
上述代码使用了占位符替换img位置
让 HTMX 动态加载:
<div class="row"> |
注意:这里添加了 hx-get 和 hx-trigger。
- hx-get 属性告诉 HTMX 向服务器发出 GET 请求,以获取元素的内容。
- hx-trigger 属性告诉 HTMX 在页面加载时触发请求。默认情况下是在点击时触发。
因此,我们需要在 SampleController 中创建一个新的映射:
@GetMapping(path = "/logo") |
为了只渲染 layout.html 模板中包含图片的片段,必须再次修改 layout.html 模板,使用 th:fragment 属性,替换hx-get和hx-trigger 属性:
<div class="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="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="content"> |
Turbo 使用自定义元素 ( turbo-frame) 来标识要替换的内容,而不是标识表单处理交互的自定义属性。表格的其余部分不变。
要转换为片段模板,我们需要th:fragment向<turbo-frame>和控制器方法添加一个声明,以匹配来自 Turbo 的唯一标头,例如Turbo-Frame。