聊聊 HTMX 吧

写在前面

最近看了几篇关于 htmx 的文章,自己也去看了一眼官网,也去油管看了一下当时 htmx 发布会的时候他们的演示,下面说几点我对这个所谓的新型起来的技术的看法,

他的来源是什么

首先说一下他虽然是一个新型的技术,但是其实他是有点炒冷饭的感觉,他其实是对 jQuery 的 [intercoolerjs](https://intercoolerjs.org/reference.html 进行了一个重写,也就是说在过去intercoolerjs这个玩意就已经可以实现类似 htmx 的效果,就是不需要绑定任何事件,直接就进行标签请求一个地址,将返回的信息直接渲染到对应的页面上,这些功能是他已经存在的,关于intercoolerjs的文章网上也是有很多的,感兴趣的可以自己去看看,引用官方一个 DEMO

<!--This is the initial UI (which would normally be generated by the userDisplayTemplate below of course)Note that the button targets the outer div which encloses the entire contact UI because that's what wewant to replace when the button is clicked.--><div id="contact-div"><div><strong>First Name</strong>: Joe</div><div><strong>Last Name</strong>: Smith</div><div><strong>Email</strong>: joesmith@example.com</div><button ic-target="#contact-div" ic-get-from="/contact/1/edit" class="btn btn-default">Click To Edit</button></div><script>//========================================================================// Mock Server-Side HTTP End Points//========================================================================$.mockjax({url: "/contact/1/edit",response: function (settings) {var mockUser = dataStore.findUser("1");this.responseText = userFormTemplate(mockUser);}});$.mockjax({url: "/contact/1",response: function (settings) {var mockUser = dataStore.findUser("1");var params = parseParams(settings.data);if (params['_method']== 'PUT') {mockUser.firstName = params['firstName'];mockUser.lastName = params['lastName'];mockUser.email = params['email'];}this.responseText = userDisplayTemplate(mockUser);}});//========================================================================// Mock Server-Side Templates//========================================================================function userFormTemplate(mockUser) {// Pretty simple bootstrap form, but note that the form uses an ic-put-to and the cancel button uses// an ic-get-from rather than the usual HTML attributesreturn '\
<form ic-put-to="/contact/1" ic-target="#contact-div"> \<div class="form-group"> \<label>First Name</label> \<input type="text" class="form-control" name="firstName" value="' + mockUser.firstName + '"> \</div> \<div class="form-group"> \<label>Last Name</label> \<input type="text" class="form-control" name="lastName" value="' + mockUser.lastName + '"> \</div> \<div class="form-group"> \<label>Email address</label> \<input type="email" class="form-control" name="email" value="' + mockUser.email + '"> \</div> \<button class="btn btn-default">Submit</button> \<button ic-get-from="/contact/1" ic-target="#contact-div" class="btn btn-danger">Cancel</button> \
</form>';}function userDisplayTemplate(mockUser) {return '\
<div><strong>First Name</strong>: ' + mockUser.firstName + '</div> \
<div><strong>Last Name</strong>: ' + mockUser.lastName + '</div> \
<div><strong>Email</strong>: ' + mockUser.email + '</div> \
<button ic-target="#contact-div" ic-get-from="/contact/1/edit" class="btn btn-default"> \Click To Edit \
</button>';}//========================================================================// Mock Data Store//========================================================================var dataStore = (function() {var mockUser = {"firstName": "Joe","lastName": "Smith","email": "joesmith@example.com"};return {findUser : function(id) {return mockUser}}})()</script>

他能做什么

说了这些也没有正式的演示过它可以做什么,它可以做的事情是直接在 html 标签上写一些 js 才可以做的东西,他的目的就是去 js 化,尽可能的少写或者不写 js 代码,因为我们知道,浏览器其实只认识 html 代码,他编译 html 代码是具有先天优势的,那么也就是说如果我们的代码中只有 html 代码那么理论上上渲染速度是很快的,但是他依赖于服务器,也就是我们前端之前的 js 代码其实没有消失,只是放到了 server 端执行了,通过上面的代码也是可以看出来的,所以它可以做的事情就是在什么标签上发送什么请求,请求返回的内容他来指定放到哪里,同时中间和用户的一个交互和反馈怎么设计,他就做这些,也仅仅做这些即可!

演示一下?

  • 我自己也试了一下他的功能,使用起来是比较简单的,可以像使用 jQuery 一样的方式直接引入 CDN 或者是 npm i 安装也是可以的,那么之后我们就可以直接在 html 中使用他的语法了

    <!DOCTYPE html>
    <html><head><meta charset="utf-8"><title>测试 htmx 的用法</title><script src="./js/htmx@1.9.5htmx.min.js" integrity="sha384-xcuj3WpfgjlKF+FXhSQFQ0ZNr39ln+hwjN3npfM9VBnUskLolQAcN80McRIVOPuO" crossorigin="anonymous"></script></head><body><script type="text/javascript">// const baseGetRequest = 'http://jsonplaceholder.typicode.com/users'// window.baseGet = baseGetRequest</script><!-- 测试基础的 get 请求 --><div hx-get="http://jsonplaceholder.typicode.com/users">Put To Messages</div><!-- 测试基础的 post 请求  并将请求的结果给到另一个 span 的元素上 --><div hx-post="http://jsonplaceholder.typicode.com/posts/1/comments" hx-target='#aimDiv'>测试一条数据</div><span id="aimDiv"></span><!-- 模拟一个对话框的请求 --><button hx-get="http://jsonplaceholder.typicode.com/users" hx-confirm="Are you sure you wish to delete your account?">Delete My Account</button><!-- 测试一个 boost 的请求 --><div hx-boost="true"><a href="http://jsonplaceholder.typicode.com/users">Blog</a></div><!-- 测试一个表单 --><div id="search-results"></div><form action="/search" method="POST"><input class="form-control" type="search" name="search" placeholder="Begin typing to search users..." hx-post="http://jsonplaceholder.typicode.com/posts/1/comments" hx-trigger="keyup changed delay:500ms, search" hx-target="#search-results" hx-indicator=".htmx-indicator"></form><!-- 测试 table --><input class="form-control" type="search" name="search" placeholder="Begin Typing To Search Users..." hx-post="http://jsonplaceholder.typicode.com/posts/1/comments" hx-trigger="keyup changed delay:500ms, search" hx-target="#search-results" hx-indicator=".htmx-indicator"><table class="table"><thead><tr><th>First Name</th><th>Last Name</th><th>Email</th></tr></thead><tbody id="search-results"></tbody></table></body>
    </html>
    

    如果里面的标签不太明白可以看一下他的官网介绍,htmx 官网虽然是英文的,但是写的还是很清晰的,一般都是可以看得懂的,

    • 上面那段代码执行结果如图:

    在这里插入图片描述

当然不用看样式,我只是试用了一下,会发现我点击 put to message 的时候 右侧直接进行了发送请求,一会之后他就直接返回了对应的内容,同时帮我渲染上去了,但是我的数据格式是 json 的,所以就显的比较不合理,大家可以忽略,因为我只是演示一下他是可以正常返回渲染的

在这里插入图片描述

它提供了哪些便利

  • 请求不需要封装函数
  • 防抖节流直接通过属性进行配置
  • 请求方式直接通过属性进行配置
  • 回参渲染到某个元素可以指定
  • 指定的方式很多(css 选择器、元素选择器等)
  • 局部内容替换成本很低
  • 前端代码量极少
  • 浏览器渲染速度很快

他有哪些劣势

  • 项目体量不可以过大,这样对服务器的压力太大
  • 过于复杂的操作不太可行,毕竟他都是通过配置的,配置就意味着定制化的需求满足程度不会太高
  • 过于依赖服务器,前端只是进行配置
  • 对Django的依赖也比较大,因为他就是配合他用的(这里我也问了一下我身边使用Django的朋友,他给的回复是:jango 内置了 web 开发工具,可以用 {} 直接获取 response 对象属性。在前后端不分离年代还是挺厉害。现在不行了)

个人推荐程度,我想说几句

可以用,可以学,但是因为适用场景不太多,所以了解即可,当有对应的业务出现的时候可以使用即可!个人还是推荐使用像 vue、react 等相对全面的框架,他是不挑场景的,几乎所有的web应用他都是可以胜任的,技术发展好不容易发展到前后分离的一个阶段,现在又想回去,不是不行,是不强烈推荐,前后端分离的好处我这里不做赘述,开发几年的人都可以体会的到。

这里吐槽一句,在中国做开发是一件很痛苦的事情,因为最新的技术一般都是国外传过来的,另外技术文档第一份都是英文的,很少有中文的,即使后面翻译之后也是不准确的,我们使用着不准确的文档用着国外人开发的语言进行使用,还可以用的很好就已经是一件很了不起的事情了,但是不代表无脑跟风就是对的,比如这个 htmx,我们明明知道他是一个炒冷饭的东西,但是奈何还是有很多人大肆的无脑宣传,只讲好的,不讲坏的,好像只要紧跟国外的脚步就一定是最新的技术,这里我是不赞成的,对技术的探索是好的,但是重复造轮子,轮子出来起个名字就按照新东西学习,除了徒增学习成本之外我想不到什么好的理由,希望这种情况以后可以少发生或者不发生,我对 htmx 没有恶意,我觉得他确实解决了一部分的应用场景,人家发布会的时候也是说了如果你的应用是需要这种场景的,我是推荐你用的,但是复杂的一些我们是不推荐的,你可以继续使用你认为好的技术栈 即可,但是传到国内就变成了了不起的新技术,对此我是无力吐槽的!但是学习本身这件事是没错的,因为只有你对所有的不同的技术栈都了解了一些,才更有可能融会贯通,技术的广度和深度都是很重要的,深度有助于研究出来新东西,广度有助于你识别技术本身的局限性和适用性,废话太多了,你们也看烦了,结束结束。

写在后面

看完这篇文章可能你们也感觉到了,这篇文章其实并没有过多的代码演示,只是说了一下他的基础用法和适用场景,因为我觉得和这个东西他本身就是解决了一部分前端的痛点,并不可以解决真正的问题,他其实就是解决了一些小而美的应用不用使用 vue 或者 react 等相对来说讲比较重的框架,毕竟配置一套前端的项目架子还是需要一点技术水平的,那么这里 htmx 就可以派上用场, 当然前期是你的后端足够支持你们返回对应的 html 代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/75775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 多线程系列Ⅶ(线程安全集合类)

线程安全集合类 前言一、多线程使用线性表二、多线程使用栈和队列三、多线程下使用哈希表 前言 在数据结构中&#xff0c;我们学习过 Java 的内置集合&#xff0c;但是我们知道&#xff0c;我们学过的大多数集合类都是线程不安全的&#xff0c;少数如 Vector&#xff0c;Stack…

小程序分销机制介绍,小程序二级分销功能有哪些?

为什么有越来越多的用户选择使用小程序&#xff1f;跟“高大上”的APP相比&#xff0c;小程序不仅可以减少下载安装的复杂流程&#xff0c;还具备操作便捷、沉淀私域数据的优势。蚓链分销小程序具备裂变二维码、实时分佣、分销身份升级、层级分佣、商品个性化佣金设定等功能&am…

TortoiseSVN 详细操作指南

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 热爱技术的小郑 1、引言 考虑以下几种情况&#xff1a; 你是否在一个…

golang面试题:json包变量不加tag会怎么样?

问题 json包里使用的时候&#xff0c;结构体里的变量不加tag能不能正常转成json里的字段&#xff1f; 怎么答 如果变量首字母小写&#xff0c;则为private。无论如何不能转&#xff0c;因为取不到反射信息。如果变量首字母大写&#xff0c;则为public。 不加tag&#xff0c…

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解 文章目录 【Spring Cloud系统】- 轻量级高可用工具Keepalive详解一、概述二、Keepalive分类2.1 TCP的keepalive2.2 HTTP的keep-alive2.3 TCP的 KeepAlive 和 HTTP的 Keep-Alive区别 三、nginx的keepalive配置3.1 nginx保持…

连接云-边-端,构建火山引擎边缘云网技术体系

近日&#xff0c;火山引擎边缘云网络产品研发负责人韩伟在LiveVideoStack Con 2023上海站围绕边缘云海量分布式节点和上百T的网络规模&#xff0c;结合边缘云快速发展期间遇到的各种问题和挑战&#xff0c;分享了火山引擎边缘云网的全球基础设施&#xff0c;融合开放的云网技术…

数据结构——七大排序[源码+动图+性能测试]

本章代码gitee仓库&#xff1a;排序 文章目录 &#x1f383;0. 思维导图&#x1f9e8;1. 插入排序✨1.1 直接插入排序✨1.2 希尔排序 &#x1f38a;2. 选择排序&#x1f38b;2.1 直接选择排序&#x1f38b;2.2 堆排序 &#x1f38f;3. 交换排序&#x1f390;3.1 冒泡排序&#…

Qt应用开发(基础篇)——工具按钮类 QToolButton

一、前言 QToolButton类继承于QAbstractButton&#xff0c;该部件为命令或选项提供了一个快速访问按钮&#xff0c;通常用于QToolBar中。 按钮基类 QAbstractButton QToolButton是一个特殊的按钮&#xff0c;一般显示文本&#xff0c;只显示图标&#xff0c;结合toolBar使用。它…

【图文并茂】c++介绍之队列

1.1队列的定义 队列&#xff08;queue&#xff09;简称队&#xff0c;它也是一种操作受限的线性表&#xff0c;其限制为仅允许在表的一端进行插入操作&#xff0c;而在表的另一端进行删除操作 一些基础概念&#xff1a; 队尾&#xff08;rear&#xff09; &#xff1a;进行插…

MFC新建内部消息

提示&#xff1a;记录一下MFC新建内部消息的成功过程 文章目录 前言一、第一阶段二、第二阶段三、第三阶段总结 前言 先说一下基本情况&#xff0c;因为要在mapview上增加一个显示加载时间的功能。然后发现是要等加载完再显示时间&#xff0c;显示在主窗口。所以就是在子线程中…

开开心心带你学习MySQL数据库之节尾篇

Java的JDBC编程 各种数据库,MySQL, Oracle, SQL Server在开发的时候,就会提供一组编程接口(API) API ~~ Application Programming Interface ~~ 应用程序编程接口 计算机领域里面的一个非常常见的概念, 给你个软件,你能对他干啥(从代码层次上的) 基于它提供的这些功能,就可以写…

AJAX学习笔记5同步与异步理解

AJAX学习笔记4解决乱码问题_biubiubiu0706的博客-CSDN博客 示例 前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>演示AJAX同步和异步</title> </head> <body> <script…

深眸科技自研轻辙视觉引擎,以AI机器视觉赋能杆号牌识别与分拣

电线杆号牌作为电力行业标识的一种&#xff0c;相当于电线杆的“身份证”&#xff0c;担负着宣传电力知识、安全警示的作用&#xff0c;用于户外使用标记输电线路电压等级、线路名称、杆塔编号等&#xff0c;能够清晰地记录电力线路杆的信息&#xff0c;并为电力线路的更改以及…

ChatGPT是如何辅助高效撰写论文及使用ChatGPT注意事项

ChatGPT发布近1年&#xff0c;各大高校对它的态度也发生了极大转变&#xff0c;今年3月发布ChatGPT禁令的牛剑等世界顶级名校也在近期解除了ChatGPT禁令&#xff0c;发布了生成式人工智能使用指南。 ChatGPT一定程度上可以解放科研人员的劳动力&#xff0c;与其直接禁止不如教…

Docker笔记-概念安装简单使用

概念 docker通用词汇。 镜像&#xff1a;Build&#xff0c;创建一个镜像。 仓库&#xff1a;Ship&#xff0c;从仓库和主机上运输镜像。 容器&#xff1a;Run&#xff0c;运行的镜像就是一个容器。 安装 Windows上安装 Docker对win10有原生的支持&#xff0c;win10下的是…

thinkphp6-简简单单地开发接口

目录 1.前言TP6简介 2.项目目录3.运行项目运行命令访问规则 4.model db使用db连接配置model编写及调用调用接口 5.返回json格式 1.前言 基于上篇文章环境搭建后&#xff0c;便开始简单学习上手开发接口…记录重要的过程&#xff01; Windows-试用phpthink发现原来可这样快速搭…

IDEA在创建包时如何把包分开实现自动分层

IDEA在创建包时如何把包分开实现自动分层 文章目录 IDEA在创建包时如何把包分开实现自动分层一、为什么要把包分开二、建包时如何把包自动分开三、如何编写配置文件路径&#xff1f; 一、为什么要把包分开 一开始的时候&#xff0c;我也一直以为包连在一起和分开没什么区别&am…

linux内核模块编译方法之模块编程详解

文章目录 一、模块传参二、模块依赖三、内核空间和用户空间四、执行流五、模块编程与应用编程的比较六、内核接口头文件查询总结 本期和大家主要分享的是驱动开发内核编译过程中对于模块是如何设计的&#xff0c;进行了详细的分享&#xff0c;从模块传参、模块依赖一直到内核空…

Linux dup dup2函数

/*#include <unistd.h>int dup2(int oldfd, int newfd);作用&#xff1a;重定向文件描述符oldfd 指向 a.txt, newfd 指向b.txt,调用函数之后&#xff0c;newfd和b.txt close&#xff0c;newfd指向a.txtoldfd必须是一个有效的文件描述符 */ #include <unistd.h> #i…

Python怎么实现更高效的数据结构和算法? - 易智编译EaseEditing

要实现更高效的数据结构和算法&#xff0c;你可以考虑以下几个方面的优化&#xff1a; 选择合适的数据结构&#xff1a; 选择最适合你问题的数据结构至关重要。例如&#xff0c;如果需要频繁插入和删除操作&#xff0c;可能链表比数组更合适。如果需要高效查找操作&#xff0…