
HTMX:无需 JavaScript 框架构建现代 Web 应用
HTMX 让你直接从 HTML 访问现代浏览器功能,无需编写 JavaScript 即可实现 AJAX 请求、WebSocket 和 SSE。
核心属性
hx-get、hx-post、hx-put、hx-delete- HTTP 方法hx-target- 响应内容放置位置hx-swap- 内容替换方式hx-trigger- 请求触发时机

快速开始
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<button hx-get="/api/message" hx-target="#result">
点击我
</button>
<div id="result"></div>
触发器
<!-- 防抖搜索 -->
<input hx-get="/api/search"
hx-trigger="keyup changed delay:300ms"
hx-target="#results"
name="q"
placeholder="搜索...">
<!-- 滚动到视口时加载 -->
<div hx-get="/api/items?page=2"
hx-trigger="intersect once"
hx-target="#item-list"
hx-swap="beforeend">
</div>
<!-- 每 5 秒轮询 -->
<div hx-get="/api/stock-price"
hx-trigger="every 5s"
hx-target="this">
</div>

服务端:返回 HTML,而非 JSON
const express = require('express');
const app = express();
app.use(express.urlencoded({ extended: true }));
let todos = [
{ id: 1, text: "买杂货", done: false },
];
// 返回 HTML 片段
app.get('/todos', (req, res) => {
const html = todos.map(todo => `
<li id="todo-${todo.id}">
<input type="checkbox" ${todo.done ? 'checked' : ''}
hx-put="/todos/${todo.id}/toggle"
hx-target="#todo-${todo.id}"
hx-swap="outerHTML">
<span>${todo.text}</span>
</li>
`).join('');
res.send(html);
});
app.post('/todos', (req, res) => {
const todo = { id: Date.now(), text: req.body.text, done: false };
todos.push(todo);
res.send(`
<li id="todo-${todo.id}">
<span>${todo.text}</span>
</li>
`);
});
带外交换
<!-- 服务端可在一次响应中更新多个区域 -->
<!-- 主内容 -->
<div id="main-content">
仪表盘已加载
</div>
<!-- 带外:同时更新头部 -->
<div id="header" hx-swap-oob="true">
更新于:2024-01-15
</div>

何时使用 HTMX
HTMX 适用于:
- CRUD 应用:管理面板、仪表盘
- 服务端渲染应用:Django、Rails、Laravel、Express
- 渐进增强:即使禁用 JS 也能工作
考虑使用 React/Vue 的场景:
- 复杂的客户端状态
- 丰富的交互式 UI 组件
- 离线能力
总结
HTMX 降低了服务端渲染应用的 JavaScript 复杂性。通过返回 HTML 片段而非 JSON,将 UI 逻辑保留在服务端,同时获得类似 SPA 的交互性。