众所周知,一段时间前我一直在关注web开发框架,总的来说,大同小异. 如何进行快速开发小应用,是一个并不简单回答的问题.这里我给出一个解决方案:Go+HTMX.
这两个技术我不过多介绍,htmx顾名思义,在html上封了一层提供与后端交互的功能. 使用Go因为它的简洁且自带GC,不像c++和rust需要仔细小心管理内存,没有选用Java/C#也是因为后两者使用通常都要带上巨大的库(大型库会带来依赖上的安装、管理以及心智负担),在开发小应用时往往没有必要. HTMX主要承担了一部分js的作用.
htmlx只有14k的大小,没有其他依赖,增强了html的功能. 再次说明,我介绍这个技术栈目的是为了快速开发中小应用,如果为了工作或是进一步学习,推荐Java/C#/Go等,再不济也是Python/PHP/Ruby.搭配vue/react/svelte/solid.
关于Go的web开发,常用Gin作为框架,主要写REST API和自带的模板引擎解析html,这里不多赘述.
下面介绍htmx的一些重要功能
HTMX
AJAX
使用html的属性发送请求.
请求方法
Attribute | Description |
---|---|
hx-get | Issues a GET request to the given URL |
hx-post | Issues a POST request to the given URL |
hx-put | Issues a PUT request to the given URL |
hx-patch | Issues a PATCH request to the given URL |
hx-delete | Issues a DELETE request to the given URL |
trigger
通过hx-trigger
设置触发动作1
2
3<div hx-post="/mouse_entered" hx-trigger="mouseenter">
[Here Mouse, Mouse!]
</div>
可以设置mofiers和filters修改默认行为.
还可以使用轮询1
2
3
4
5
6<div hx-get="/news" hx-trigger="every 2s"></div>
<div hx-get="/messages"
hx-trigger="load delay:1s"
hx-swap="outerHTML"
>
</div>
设置indicator表明已经发出请求1
2
3
4<button hx-get="/click">
Click Me!
<img class="htmx-indicator" src="/spinner.gif">
</button>1
2
3
4
5
6
7
8
9.htmx-indicator{
display:none;
}
.htmx-request .htmx-indicator{
display:inline;
}
.htmx-request.htmx-indicator{
display:inline;
}
当htmx发出请求时,它将把一个htmx-request类放到一个元素上(如果指定,可以是请求元素或另一个元素)。htmx-request类会使带有html-indicator类的子元素的不透明度变为1。
可以设置修改的元素.1
2
3
4
5
6<div>
<button hx-get="/click" hx-indicator="#indicator">
Click Me!
</button>
<img id="indicator" class="htmx-indicator" src="/spinner.gif"/>
</div>
target
响应默认加载到请求的元素中,可以修改1
2
3
4
5
6
7<input type="text" name="q"
hx-get="/trigger_delay"
hx-trigger="keyup delay:500ms changed"
hx-target="#search-results"
placeholder="Search..."
>
<div id="search-results"></div>
swap
htmx提供了几种不同的方法来将返回的HTML交换到DOM.默认情况下,内容会替换目标元素的innerHTML.可以通过使用hx-swap属性来修改这个值:
Name | Description |
---|---|
innerHTML | the default, puts the content inside the target element |
outerHTML | replaces the entire target element with the returned content |
afterbegin | prepends the content before the first child inside the target |
beforebegin | prepends the content before the target in the target’s parent element |
beforeend | appends the content after the last child inside the target |
afterend | appends the content after the target in the target’s parent element |
delete | deletes the target element regardless of the response |
none | does not append content from response (Out of Band Swaps and Response Headers will still be processed) |
以上就是htmx中Ajax的基本使用,如果知道ajax的运作,那么使用就不会太难.
属性继承
1 | <div hx-confirm="Are you sure?"> |
上面两个button继承了hx-confirm的值1
2
3
4
5
6
7
8
9
10
11<div hx-confirm="Are you sure?">
<button hx-delete="/account">
Delete My Account
</button>
<button hx-put="/account">
Update My Account
</button>
<button hx-confirm="unset" hx-get="/">
Cancel
</button>
</div>
利用unset取消
增强表单和链接
HTML支持使用hx-boost属性“增强”常规HTML锚和表单.该属性将把所有锚标记和表单转换为AJAX请求,默认情况下,这些请求以页面主体为目标。1
2
3<div hx-boost="true">
<a href="/blog">Blog</a>
</div>
这个div中的锚标记将向/blog发出一个AJAX GET请求,并将响应交换到body标记中
配置响应处理
htmx期望对它发出的AJAX请求的响应是HTML,通常是HTML片段(尽管与hx-select标记匹配的完整HTML文档也很有用).然后,HTML将返回的HTML交换到指定目标的文档中,并使用指定的交换策略.
有时您可能不希望在交换中执行任何操作,但仍然可能触发客户端事件.
对于这种情况,默认情况下,您可以返回204 - No Content响应代码,并且html将忽略响应的内容.
在服务器错误响应的事件中(例如404或501),html将触发html:responseerror事件,你可以处理。
如果出现连接错误,将触发html:sendError事件。1
2
3
4
5responseHandling: [
{code:"204", swap: false}, // 204 - No Content by default does nothing, but is not an error
{code:"[23]..", swap: true}, // 200 & 300 responses are non-errors and are swapped
{code:"[45]..", swap: false, error:true}, // 400 & 500 responses are not swapped and are errors
]
可以配置下面这些选项:
code
- a String representing a regular expression that will be tested against response codes.swap
-true
if the response should be swapped into the DOM,false
otherwiseerror
-true
if htmx should treat this response as an errorignoreTitle
-true
if htmx should ignore title tags in the responseselect
- A CSS selector to use to select content from the responsetarget
- A CSS selector specifying an alternative target for the responseswapOverride
- An alternative swap mechanism for the response
配置请求头和响应头
Request Headers
htmx includes a number of useful headers in requests:
Header | Description |
---|---|
HX-Boosted | indicates that the request is via an element using hx-boost |
HX-Current-URL | the current URL of the browser |
HX-History-Restore-Request | “true” if the request is for history restoration after a miss in the local history cache |
HX-Prompt | the user response to an hx-prompt |
HX-Request | always “true” |
HX-Target | the id of the target element if it exists |
HX-Trigger-Name | the name of the triggered element if it exists |
HX-Trigger | the id of the triggered element if it exists |
Response Headers
HX-Location
- allows you to do a client-side redirect that does not do a full page reloadHX-Push-Url
- pushes a new url into the history stackHX-Redirect
- can be used to do a client-side redirect to a new locationHX-Refresh
- if set to “true” the client-side will do a full refresh of the pageHX-Replace-Url
- replaces the current URL in the location barHX-Reswap
- allows you to specify how the response will be swapped. See hx-swap for possible valuesHX-Retarget
- a CSS selector that updates the target of the content update to a different element on the pageHX-Reselect
- a CSS selector that allows you to choose which part of the response is used to be swapped in. Overrides an existinghx-select
on the triggering elementHX-Trigger
- allows you to trigger client-side eventsHX-Trigger-After-Settle
- allows you to trigger client-side events after the settle stepHX-Trigger-After-Swap
- allows you to trigger client-side events after the swap step
htmx请求的顺序:
- 元素被trigger
- 收集需要发送的数据
htmx-request
类被放在元素上- 通过AJAX异步地请求
- 获得响应后与
htmx-swapping
类地内容转换 - 可选的swap延迟
- 实际交换内容完成
htmx-swapping
类被移除htmx-added
类被添加到每个更改的元素上htmx-settling
类添加到target上- 默认延迟
- DOM完成
htmx-settling
被移除htmx-added
类被移除
- 获得响应后与