Alpine.js:像使用 jQuery 一样使用,像 Vue 一样编写,并受 TailwindCSS 启发的 JavaScript 框架

Avatar of Hugo Di Francesco
Hugo Di Francesco

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 价值 200 美元的免费积分!

我们拥有许多人已经使用和喜欢的庞大 JavaScript 框架,包括 React、Vue、Angular 和 Svelte。我们还需要另一个 JavaScript 库吗?让我们看一下 Alpine.js,您可以自行决定。Alpine.js 适用于希望构建单页应用程序 (SPA) 的开发人员。它轻量级(~7kB 压缩后)并旨在编写以标记为中心的客户端 JavaScript。

语法借鉴了 Vue 和 Angular 指令。这意味着如果您以前使用过它们,它会感觉很熟悉。但是,再次强调,Alpine.js 不是为了构建 SPA,而是为了用少量 JavaScript 增强您的模板。

例如,以下是一个交互式“警报”组件的 Alpine.js 演示。

警报消息使用x-model="msg"双向绑定到输入。警报消息的“级别”使用反应式level属性设置。当msglevel都有值时,警报会显示。

它就像 jQuery 和 JavaScript 的替代品,但具有声明性渲染

Alpine.js 是 jQuery 和原生 JavaScript 的 Vue 模板风格替代品,而不是 React/Vue/Svelte/WhateverFramework 的竞争对手

由于 Alpine.js 的年龄不到一年,因此它可以对 jQuery 无法做出的 DOM API 做出假设。让我们简要比较一下这两者。

查询与绑定

jQuery 的大部分大小和功能都来自对命令式 DOM API 的跨浏览器兼容性层的形式——这通常被称为jQuery Core,并具有可以查询 DOM 并操作 DOM 的功能。

Alpine.js 对 jQuery 核心 的回答是一种声明式方法,可以使用 x-bind 属性绑定指令 将数据绑定到 DOM。它可用于将任何属性绑定到 Alpine.js 组件上的反应式数据。Alpine.js 与其声明式视图库同类 (React、Vue) 一样,提供了 x-ref 作为一种逃生舱,以便在绑定不足时(例如,当集成需要传递 DOM 节点的第三方库时)直接从 JavaScript 组件代码访问 DOM 元素。

处理事件

jQuery 还提供了一种处理、创建和触发事件的方法。Alpine.js 提供了 x-on 指令$event 魔术值,允许 JavaScript 函数处理事件。为了触发(自定义)事件,Alpine.js 提供了 $dispatch 魔术属性,它是浏览器 事件和派发事件 API 的薄包装器。

效果

jQuery 的关键功能之一是它的效果,或者更确切地说,是它编写简单动画的能力。在 jQuery 中,我们可能使用slideUpslideDownfadeInfadeOut 属性来创建效果,而 Alpine.js 提供了一组 x-transition 指令,它们在元素的整个转换过程中添加和删除类。这在很大程度上受到 Vue Transition API 的启发。

此外,由于 Fetch API 或利用第三方 HTTP 库(例如 axios、ky、superagent),jQuery 的 Ajax 客户端在 Alpine.js 中没有规范解决方案。

插件

还值得一提的是 jQuery 插件。Alpine.js 生态系统中还没有可比的插件(至少目前还没有)。共享 Alpine.js 组件相对简单,通常只需要简单的复制粘贴操作。Alpine.js 组件中的 JavaScript 是“函数”,并且通常不访问 Alpine.js 本身,这使得它们可以通过在不同页面上使用script标签包含它们来轻松共享。任何魔术属性都在 Alpine 初始化或传递到绑定时添加,例如x-on绑定中的$event

目前还没有 Alpine.js 扩展的示例,但有一些问题和拉取请求用于添加从其他库连接到 Alpine.js 的“核心”事件。关于添加自定义指令的功能也有一些讨论。Alpine.js 创建者 Caleb Porzio 的立场似乎是根据 Vue API 来制定 API 决策,因此我认为任何未来的扩展点都将受到 Vue.js 提供的功能的启发。

大小

Alpine.js 比 jQuery 更轻量级,压缩后大小为 21.9kB——压缩后为 7.1kB——而 jQuery 压缩后为 87.6kB——压缩后为 30.4kB。只有 23% 的大小!

这很可能是由于 Alpine.js 侧重于为 DOM 提供声明式 API 的方式(例如属性绑定、事件监听器和转换)。

Bundlephobia 将这两者进行了分解

为了进行比较,Vue 压缩后大小为 63.5kB(压缩后为 22.8kB)。Alpine.js 如何在 API 等效于 Vue 的情况下更轻量级?Alpine.js 没有实现虚拟 DOM。相反,它直接修改 DOM,同时公开与 Vue 相同的声明式 API。

让我们看一个例子

Alpine 很紧凑,因为应用程序代码本质上是声明性的,并且通过模板声明。例如,以下是一个使用 Alpine.js 的神奇宝贝搜索页面

此示例显示了如何使用x-data设置组件,以及一个在加载时返回初始组件数据、方法和x-init以运行该函数的函数。

Alpine.js 中的绑定和事件监听器,语法与 Vue 模板非常相似。

  • Alpine:x-bind:attribute="express"x-on:eventName="expression",简写分别是:attribute="expression"@eventName="expression"
  • Vue:v-bind:attribute="express"v-on:eventName="expression",简写分别是:attribute="expression"@eventName="expression"

列表渲染是在template元素上使用x-for实现的,条件渲染是在template元素上使用x-if实现的。

请注意,Alpine.js 没有提供完整的模板语言,因此没有插值语法(例如 Vue.js、Handlebars 和 AngularJS 中的{{ myValue }})。相反,绑定动态内容是使用x-textx-html指令完成的(它们直接映射到对Node.innerTextNode.innerHTML的底层调用)。

使用 jQuery 的等效示例是一项您可以尝试的练习,但经典风格包括几个步骤

  • 使用$('button').click(/* callback */)命令式地绑定到按钮点击事件。
  • 在此“点击回调”中,从 DOM 获取输入值,然后使用它来调用 API。
  • 调用完成后,DOM 会使用从 API 响应生成的新的节点进行更新。

如果您想并排比较 jQuery 和 Alpine.js 中相同代码的差异,Alex JustesenjQueryAlpine.js 中创建了相同的字符计数器。

重回流行:以 HTML 为中心的工具

Alpine.js 从 TailwindCSS 中汲取灵感。Alpine.js 仓库中的介绍将其称为“JavaScript 的 Tailwind”。

为什么这很重要?

Tailwind 的一个卖点是它“提供低级实用程序类,让您无需离开 HTML 即可构建完全自定义的设计”。Alpine 就是这么做的。它在 HTML 内部工作,因此无需像在 Vue 或 React 中那样在 JavaScript 模板中工作。社区中引用的许多 Alpine 示例甚至根本不使用 script 标签!

让我们看一个例子来进一步说明区别。这是一个可访问的 Alpine.js 导航菜单,它根本没有使用 script 标签。

此示例在 Alpine.js 之外(使用 `id` 引用)利用了 `aria-labelledby` 和 `aria-controls`。Alpine.js 确保“切换”元素(它是一个按钮)具有 `aria-expanded` 属性,当导航展开时,该属性为 `true`,折叠时为 `false`。此 `aria-expanded` 绑定也应用于菜单本身,我们通过绑定到 `hidden` 来显示/隐藏其中的链接列表。

以标记为中心意味着 Alpine.js 和 TailwindCSS 示例易于共享。只需将其复制粘贴到运行 Alpine.js/TailwindCSS 的 HTML 中即可。无需充满编译并渲染成 HTML 的模板的疯狂目录!

由于 HTML 是 Web 的基本构建块,因此这意味着 Alpine.js 非常适合增强服务器端渲染的(Laravel、Rails、Django)或静态站点(Hugo、Hexo、Jekyll)。将数据与这种工具集成可能很简单,只需将一些 JSON 输出到 `x-data="{}"` 绑定中。将一些 JSON 从您的后端/静态站点模板直接传递到 Alpine.js 组件的能力避免了构建“另一个 API 端点”的麻烦,该端点仅提供 JavaScript 小部件所需的数据片段。

无需构建步骤的客户端

Alpine.js 的设计就是从公共 CDN 直接包含脚本。它的开发体验就是为此而定制的。这就是为什么它非常适合与 jQuery 进行比较和替换的原因:它可以轻松集成并消除构建步骤。

虽然这不是传统的使用方式,但 Vue 的捆绑版本可以直接链接起来。Sarah Drasner 有一篇非常好的文章,展示了 jQuery 被 Vue 替换 的示例。但是,如果您在没有构建步骤的情况下使用 Vue,那么您就主动放弃了

  • Vue CLI
  • 单文件组件
  • 更小/更优化的捆绑包
  • 严格的 CSP(内容安全策略),因为 Vue 内联模板在客户端评估表达式

所以,是的,虽然 Vue 拥有一个无构建的实现,但它的开发体验实际上依赖于 Vue CLI。这也可以说是针对 React 的 Create React App 和 Angular CLI。不进行构建会剥夺这些框架的最佳品质。

就是这样!Alpine.js 是一款现代的、以 CDN 为首的库,它以小负载带来声明式渲染——这一切都无需构建步骤和模板,而其他框架都需要这些。结果是一种以 HTML 为中心的方案,不仅类似于现代 jQuery,而且也是它的绝佳替代品。

如果您正在寻找一个不会强迫您进入 SPA 架构的 jQuery 替代品,那么就试试 Alpine.js 吧!有兴趣吗?您可以在 Alpine.js Weekly 上了解更多信息,这是一个关于 Alpine.js 新闻和文章的免费每周摘要。