我把项目中的 HTMX 模块替换成了这个模块🔥
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
太长不看
我之前写过一篇文章,介绍如何使用这个模块来替代 Next.js,但在某些情况下,它更像是一个轻量级版本。
现在,我们终于要谈到具体细节了,这次替换完全合情合理,并非牵强附会。这两个模块都处理来自服务器的 HTML,而且概念相似,所以这绝对是一个不错的选择。
好,我们开始吧!🏎️
⚙️ 从简单的例子
让我们从最简单的例子开始——遥控器。你可以这样做:
<body>
<div class="clicker-container">
<h1>HTMX Clicker</h1>
<div class="click-count" id="counter" hx-swap-oob="true">0</div>
<button
class="click-button"
hx-post="/click"
hx-target="#counter"
hx-swap="innerHTML"
>
Click!
</button>
</div>
</body>
乍一看不错,最重要的是,它功能齐全。但现在,让我们以 HMPL.js 为例:
<body></body>
<script>
const templateFn = hmpl.compile(`
<div class="clicker-container">
<h1>HMPL Clicker</h1>
<div class="click-count" id="counter">
{{#request src="/click" after="click:#btn"}}
{{/request}}
</div>
<button id="btn">Click!</button>
</div>
`);
const clicker = templateFn().response;
document.querySelector("body").append(clicker);
</script>
正如我们所见,这里有两种不同的方法:一个模块完全依赖于当前的 DOM,而另一个模块则不依赖于 DOM,而是通过 JavaScript 生成。但总的来说,它们使用相同的接口和通用的方法。只是这里存在一个主要问题:第一种方法只提供了请求所需的最少设置。
🔍 问题(故意)
在 HTML 中,它的设计初衷是让开发者尽可能少地依赖 JavaScript,因此,这个模块最严重的问题就出在这里——几乎无法对请求进行任何自定义。
所以,当然可以,你可以body这样发送:
<button
class="click-button"
hx-post="/click"
hx-target="#counter"
hx-swap="innerHTML"
hx-vars='{"action": "increment"}'
>
Click!
</button>
但是,如果我们想要实现更多功能,就会发现这要么不可能,要么很难实现。而且,这同样是有意为之,因为该模块的全部意义就在于易用性。
此外,第二个问题是,我们收到了请求,但它们是通过XMLHTTPRequest一个已有25年以上历史的标准发送的。没错,最后一次更新是在2010年代初,但事实是……
在 HMPL 中,几乎完全可定制fetch,也就是说,ECMAScript 中的所有新内容默认情况下都已得到支持。
🔗 复杂示例
让我们用一个更复杂的例子来展示如何在项目中替换 HTML。
<div id="wrapper">
<form
id="form"
hx-post="/api/register"
hx-target="#response"
hx-indicator="#loading-indicator"
hx-swap="innerHTML"
hx-include="this"
>
<div class="form-example">
<label for="login">Login: </label>
<input type="text" name="login" id="login" required /><br/>
<label for="password">Password: </label>
<input type="password" name="password" id="password" required />
</div>
<div class="form-example">
<input type="submit" value="Register!" />
</div>
</form>
<div id="response"></div>
<div id="loading-indicator" class="htmx-indicator">
<p>Loading...</p>
</div>
</div>
现在我们有一个表单,需要将其发送到服务器。该hx-include属性包含数据FormData。此外,我们还有一个请求指示。现在,让我们尝试用 HTML 实现同样的功能:
<body></body>
<script>
const templateFn = compile(
`<div id="wrapper">
<form onsubmit="function prevent(e){e.preventDefault();};return prevent(event);" id="form">
<div class="form-example">
<label for="login">Login: </label>
<input type="text" name="login" id="login" required /><br/>
<label for="password">Password: </label>
<input type="password" name="password" id="password" required />
</div>
<div class="form-example">
<input type="submit" value="Register!" />
</div>
</form>
<p>
{{#request
src="/api/register"
after="submit:#form"
repeat=true
}}
{{#indicator trigger="pending"}}
<div class="indicator">
<p>Loading...</p>
</div>
{{/indicator}}
{{/request}}
</p>
</div>`
);
const initFn = (ctx) => {
const event = ctx.request.event;
return {
body: new FormData(event.target, event.submitter),
credentials: "same-origin",
};
};
const obj = templateFn(initFn);
document.querySelector("body").append(obj.response);
</script>
在这里可以清楚地看到,我们可以像在 HTML 中一样做同样的事情,但是有一个小小的区别,我们可以操作它form,从中获取任何数据并修改我们的请求。
📊 尺寸对比
我不会对此保持沉默,但从这个角度来评估仍然很有意义。使用 HTML 可以减少代码量。让我们用一个简单的例子来比较一下应用程序的大小:
📦 HTMX:
📦 HMPL:
由于一切都非常简洁,HTMX 在体积方面是无可争议的领导者,但你可以看到,在这个例子中,应用程序的大小并没有太大的区别。
虽然与其他方法相比,HMPL 在维度方面通常表现良好:
当然,如果我们降低 js 的功能,只保留最基本的功能,那么源文件的大小就会更小。
✅ 结论
当然,您可以继续使用 HTML,但本文旨在提供一种替代方案。任务各不相同,人们并非总是需要功能最精简的应用程序,也并非总是愿意为此牺牲功能。在处理服务器端任务时,如果是大型应用程序,您仍然需要以某种方式自定义请求。但一切都取决于具体任务。
非常感谢您阅读这篇文章❤️!
你觉得这个方案怎么样?欢迎在评论区留言!
实用链接:
文章来源:https://dev.to/anthonymax/i-replaced-the-htmx-in-the-project-to-this-module-56bc


