聊聊 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,一经查实,立即删除!

相关文章

jQuery选择器参考手册

选择器实例选取*$(“*”)所有元素#id$(“#lastname”)id“lastname” 的元素.class$(“.intro”)class“intro” 的所有元素.class,.class$(“.intro,.demo”)class 为 “intro” 或 “demo” 的所有元素element$(“p”)所有 <p> 元素el1,el2,el3$(“h1,div,p”)所有 <…

数据库管理系统,数据库,sql的基本介绍以及它们之间的关系

数据库管理系统&#xff08;Database Management System&#xff0c;简称DBMS&#xff09;是一种软件工具或系统&#xff0c;用于管理和维护数据库的创建、访问、更新和管理。DBMS允许用户在数据库中存储、检索和操作数据&#xff0c;同时提供了数据安全性、完整性和一致性的控…

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

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

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

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

TortoiseSVN 详细操作指南

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

设计模式-代理模式Proxy

代理模式Proxy 代理模式 (Proxy)1) 静态代理1.a) 原理解析1.b) 使用场景1.c) 静态代理步骤总结 2) 动态代理2.a) 基于 JDK 的动态代理实现步骤2.b) 基于 CGLIB 的动态代理实现步骤2.c) Spring中aop的使用步骤 代理模式 (Proxy) 代理设计模式&#xff08;Proxy Design Pattern&…

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保持…

在Docker中运行PostgreSQL数据库

1.下载Docker 2.设置DockerHub账号 3.运行Docker并下载Image 4.启动PostgreSQL Image 5.连接到数据库运行SQL docker run --name some-postgres -p 5432:5432 -e POSTGRES_PASSWORDmysecretpassword -d postgres 开放端口从Docker容器到主操作系统&#xff0c;这将允许我们…

【GAN小白入门】Semi-Supervised GAN 理论与实战

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊🚀 文章来源:K同学的学习圈子论文原文:Semi-Supervised Learning with Generative Adversarial Networks.pdf在学习GAN的时候你有没有想过这样一个问题呢,如果我们生成的图像是带有标签的,例如数…

详解 sudo usermod -aG docker majn

这个命令涉及到几个 Linux 系统管理的基础概念&#xff0c;包括 sudo、usermod 和用户组管理。我们可以逐一地解析它们&#xff1a; sudo: sudo&#xff08;superuser do&#xff09;允许一个已经被授权的用户以超级用户或其他用户的身份执行一个命令。当使用 sudo 前缀一个命令…

Python总结上传图片到服务器并保存的两种方式

一、前言 图片保存到服务器的两种方法&#xff1a; 1、根据图片的 URL 将其保存到服务器的固定位置 2、根据 request.FILES.get("file") 方式从请求中获取上传的图片文件&#xff0c;并将其保存到服务器的固定位置 二、方法 1、图片的 URL 要根据图片的 URL 将…

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

近日&#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 冒泡排序&#…

【MyBatis】三、ResultMap与多表查询的处理

ResultMap与多表查询的处理 当字段名与实类名不一致时 使用别名进行处理 字段名&#xff1a;emp_name 实体类名&#xff1a;empName 映射文件中写法&#xff1a; <select id"getAllEmp" resultType"Emp">select eid, emp_name empName, age, se…

210. 课程表 II(leetcode210,ArrayList类型的数组创建,拓扑排序)-------------------Java实现

210. 课程表 II&#xff08;leetcode210&#xff0c;ArrayList类型的数组创建&#xff0c;拓扑排序&#xff09;-------------------Java实现 题目表述 现在你总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses - 1。给你一个数组 prerequisites &#xff0c;其…

【React】React获取URL参数,根据URL参数隐藏页面元素

React获取URL参数&#xff0c;根据URL参数隐藏页面元素 AI推荐方法 如果您想使用React获取URL参数并相应地隐藏页面元素&#xff0c;可以按照以下步骤进行操作&#xff1a; 导入React和React DOM&#xff1a; import React from react; import ReactDOM from react-dom;创建…

react 中 antd 的 样式和 tailwind 样式冲突

问题原因&#xff1a;在使用 tailwindcss 时&#xff0c;会导入大量的 tailwindcss 默认属性&#xff0c;而默认样式中 button, [typebutton] 包含了 background-color: transparent; 从而导致 antd Button 按钮背景色变成透明。解决办法&#xff1a;禁止 tailwindcss 的默认属…

单例模式(Singleton Pattern)

单例模式 1、掌握单例模式的应用场景。1-1、饿汉式单例1-2、懒汉式单例1-2-1、 测试类:1-2-2、 main1-2-3、 控制台结果1-2-4、 改进 加锁 `synchronized `1-2-5、 控制台输出1-2-6、 再改进,使用双检锁,懒汉式双重检查锁定(Lazy initialization with double-checked locki…

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

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