聊聊 HTMX 吧

news2024/11/27 10:33:57

写在前面

最近看了几篇关于 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 we
  want 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 attributes
      return '\
<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.coloradmin.cn/o/979708.html

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

相关文章

【每日一题】73. 矩阵置零

73. 矩阵置零 - 力扣&#xff08;LeetCode&#xff09; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[…

一文讲解Transformer

我们本篇文章来详细讲解Transformer: 首次提出在&#xff1a;Attention is all you need (arxiv.org) 简单来说&#xff0c;Transfomer就是一种Seq2seq结构&#xff0c;它基于多头自注意力机制&#xff0c;解决了传统RNN在计算过程中不能够并行化的问题。即相较于RNN而言&…

c语言每日一练(14)【加强版】

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。博主有时会将一些难题综合成每日一练加强版&#xff0c;加强版是特殊的&#xff0c;它仅包含5道选择题&#x…

如何将home目录空间扩充到根目录下

目录 1、查看查看磁盘使用情况2、扩容思路3、卸载并删除/home4、扩大/root逻辑卷5、扩大/文件系统6、重建/home逻辑卷7、创建/home文件系统8、将新建的文件系统挂载到/home目录下9、恢复/home并删除备份10、再次查看看磁盘存储 系统&#xff1a;centos7.9 1、查看查看磁盘使用…

shell指令练习

一、使用cut截取出Ubuntu用户的家目录&#xff0c;要求&#xff1a;不能使用":"作为分割 ubuntuubuntu:01_day$ grep "^Ubuntu" /etc/passwd -ni | cut -d "/" -f 2,3 | cut -c 1-11 home/ubuntu

【算法专题突破】双指针 - 和为s的两个数字(6)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;剑指 Offer 57. 和为s的两个数字 - 力扣&#xff08;Leetcode&#xff09; 这道题题目就一句话但是也是有信息可以提取的&#xff0c; 最重要的就是开始的那句话&#…

SonarQube介绍和安装

docker安装postgres数据库 docker安装sonarqube 安装前在官网上确定一下可用的版本号 创建sonarqube_docker目录 本实验中&#xff0c;jdk,maven,jenkins,postgres,sonarqube都安装在同一台服务器上。 docker compose启动 修改虚拟机内存 sonarqube启动成功 默认用户名和密…

Javase | 字符编码、转义字符、方法执行过程中的 “内存分配”

目录&#xff1a; 字符编码转义字符&#xff1a;转义字符在控制台上输出 “反斜杠字符”在控制台上输出 “单引号字符” 方法执行过程中的 “内存分配” 字符编码 为了让计算机可以表示现实世界中的文字&#xff0c;我们需要人为进行干涉&#xff0c;需要人负责提前制定 “文字…

Linux系统之mkdir与rmdir命令的基本使用

Linux系统之mkdir与rmdir命令的基本使用 一、mkdir命令介绍1.1 mkdir命令简介1.2 mkdir命令的由来 二、mkdir命令的使用帮助2.1 mkdir命令的help帮助信息2.2 mkdir命令的选项解释 三、mkdir命令的基本使用3.1 查看mkdir的版本3.2 创建一个新目录3.3 创建目录时设置目录权限3.4 …

【MySQL基础|第一篇】——谈谈SQL中的DDL语句

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】&#x1f388; 本专栏旨在分享学习MySQL的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 前言&#xff…

vue优化首屏加载时间优化-cdn引入第三方包

前言 为什么要进行首屏加载优化&#xff0c;因为随着我们静态资源和第三方包和代码增加&#xff0c;压缩之后包会越来越大 随着网络的影响&#xff0c;在我们第一输入url请求资源时候&#xff0c;网络阻塞&#xff0c;加载时间长&#xff0c;用户体验不好 仔细观察后就会发现…

linux和macOS平台中python语言文件上传的一处不同实现

背景 linux系统&#xff0c; python语言&#xff0c;tornado框架 现象 x文件在macOS平台可正常上传&#xff0c; linux平台上传失败。 x文件说明 文件名&#xff1a;xxxx秘密 .mp3 文件格式&#xff1a;mp3 原因 文件名包含\x20\x7f导致, \x20是设备控制&#xff0c; \…

Android逆向工程【黑客帝国】

Android逆向是一门艺术&#xff0c;涵盖的范畴非常广&#xff0c;要学习的东西也很多&#xff0c;如果是为了就业目的&#xff0c;学习的偏向性一定要掌握好。而Android逆向必须掌握的技能有以下&#xff1a; 负责安卓程序的加解密和数据传输分析、拆解、逆向等工作;逆向APK,了…

Agisoft/PhotoScan手动对齐照片

所以我到网上查了一下资料&#xff0c;了解了如何通过添加标记的方式&#xff0c;手动对齐照片。参考文档是PhotoScan的用户手册(http://www.agisoft.com/pdf/photoscan-pro_1_4_en.pdf)。 手动对齐照片&#xff0c;需要在未对齐照片上添加四个及以上标记&#xff0c;并在已对…

Android——数据存储(一)(二十一)

1. 数据存储 1.1 知识点 &#xff08;1&#xff09;掌握Android数据存储的分类&#xff1b; &#xff08;2&#xff09;可以使用SharedPreferences存储数据。 1.2 具体内容 对于我们数据的存储而言&#xff0c;Android一共提供了5个数据存储的方式&#xff1a;SharedPrefe…

Swift 另辟蹊径极速生成图片的缩略图

功能需求 在 App 开发中,创建图片缩略图是一种很常见的操作。但是超大图片如何快速且便捷的生成指定尺寸的缩略图呢? 如上图所示:我们极速生成缩略图比常规方式快了将近 27 倍之多!且生成代码没有用任何第三方库,完全是  原生实现。 在上面演示中包含几张数码相机原始…

huggingface 使用入门笔记

概念 Hugging Face Hub​​和 Github 类似&#xff0c;都是Hub(社区)。Hugging Face可以说的上是机器学习界的Github。Hugging Face为用户提供了以下主要功能&#xff1a; ​模型仓库&#xff08;Model Repository&#xff09;​​&#xff1a;Git仓库可以让你管理代码版本、…

动态规划区间dp之647回文子串

题目&#xff1a; 给你一个字符串 s &#xff0c;找出其中最长的回文子序列&#xff0c;并返回该序列的长度。 子序列定义为&#xff1a;不改变剩余字符顺序的情况下&#xff0c;删除某些字符或者不删除任何字符形成的一个序列。 示例&#xff1a; 题目链接&#xff1a;647.…

Android 线程池源码详解(一)

线程池的创建是通过Executors 构造出来的&#xff0c;这是个典型的工厂类&#xff0c;使用了工厂模式。常用的有四种线程池&#xff1a; 分别是newFixedThreadPool&#xff0c;newSingleThreadExecutor&#xff0c; newCachedThreadPool&#xff0c;newScheduledThreadPool&am…

小白备战大厂算法笔试(二)——数组、链表、列表

常见数据结构 常见的数据结构包括数组、链表、栈、队列、哈希表、树、堆、图&#xff0c;它们可以从“逻辑结构”和“物理结构”两个维度进行分类。 逻辑结构可被分为“线性”和“非线性”两大类。线性结构比较直观&#xff0c;指数据在逻辑关系上呈线性排列&#xff1b;非线…