Stimulus.js 简介
已发表: 2022-03-10网络发展得非常快,为您的前端选择一种在一年内感觉合理的方法是很棘手的。 作为一名开发人员,我最大的恐惧是拿起一个有一段时间没有接触过的项目,并且发现他们使用的任何方法的文档要么不存在,要么在网上不容易找到。
大约一年前,我开始使用 Stimulus,我对自己交付的代码感到非常高兴。 这是一个大约 30kb 的库,它鼓励在您的应用程序中添加少量可重复使用的 JavaScript,其组织方式使得它在可访问的 HTML 中几乎没有提示在哪里找到它所连接的 JavaScript。 它使理解一段 JavaScript 将如何与您的页面交互几乎就像阅读伪代码一样。
Stimulus 由 Basecamp 的团队创建——他们最近发布了HEY电子邮件服务——以帮助维护他们为 Web 应用程序编写的 JavaScript。 从历史上看,Basecamp 在维护他们的开源项目方面一直做得很好,所以我很有信心 Stimulus 已经过彻底的测试,并将在未来几年内得到维护。
Stimulus 让我能够以一种感觉可重用且平易近人的方式构建应用程序。 虽然我认为 Stimulus 不会像 React 和 Vue 那样接管网络,但我认为它是一个值得学习的工具。
术语
像所有框架一样,Stimulus 具有描述某些事物的首选术语。 幸运的是(也是我喜欢刺激的主要原因之一),你只需要知道两个:
- 控制器
这是指 JavaScript 类的实例,它们是应用程序的构建块。 可以肯定地说,当我们谈论刺激控制器时,我们谈论的是 JavaScript 类。 - 标识符
这是我们将使用 Stimulus 代码库通用的数据属性在 HTML 中引用控制器的名称。
让我们跳入刺激!
在以下几个示例中,我将使用您可以放入浏览器的代码,通过 unpkg.com 分发的库立即开始。 稍后,我将介绍强烈鼓励使用的 webpack 方法,因为它可以改进代码的组织,并且是 Stimulus 手册中使用的方法。
样板
一旦你理解了上述代码片段的要点,你就会知道如何轻松地选择一个使用 Stimulus 的项目。
非常棒,对吧? 让我们看看一切都在做什么!
application.start
这一行告诉 Stimulus 将侦听器添加到页面。 如果您在添加任何 Stimulus 代码之前只在页面顶部调用它一次,它将返回主 Stimulus 控制器的一个实例,其中包括用于告诉 Stimulus 您想要连接的类的方法register
给它。
控制器
data-controller
属性将我们的 HTML 元素连接到我们的 JavaScript 类的实例。 在这种情况下,我们使用标识符“counter”将CounterController
JavaScript 类的实例连接到我们的div
元素。 我们通过application.register
方法告诉了 Stimulus 这个标识符和控制器之间的连接。
Stimulus 将持续监控您的页面何时添加和删除具有此属性的元素。 当带有data-controller
属性的新 HTML 片段添加到页面时,它将初始化相关控制器类的新实例,然后连接 HTML 元素。 如果您从页面中删除该元素,它将调用控制器类的disconnect
方法。
行动
Stimulus 使用数据属性data-action
来明确定义将运行控制器的哪个功能。 使用语法event->controller#function
任何阅读 HTML 的人都可以看到它的作用。 这特别有用,因为它降低了来自其他文件的意外代码的风险,从而更容易导航代码库。 当我第一次看到 Stimulus 鼓励的方法时,感觉就像阅读伪代码一样。
在上面的示例中,当按钮触发“click”事件时,它将被传递到我们的“counter”控制器中的addOne
函数。
目标
目标是一种明确定义控制器可以使用哪些元素的方法。 从历史上看,我使用了 ID、CSS 类名和数据属性的混合来实现这一点,因此只有一个“这就是实现它的方法”如此明确,使代码更加一致。
这需要通过targets
函数在控制器类中定义目标名称,并通过data-target
将名称添加到元素中。
一旦你设置了这两个部分,你的元素将在你的控制器中可用。 在这种情况下,我设置了名称为“输出”的目标,并且可以通过我们控制器中的函数中的this.outputTarget
访问它。
重复目标
如果您有多个具有相同名称的目标,您可以使用 target 方法的复数版本来访问它们,在这种情况下,当我调用this.outputTargets
时,它将返回一个包含我的两个具有属性data-target="hello.output"
的 div 的数组data-target="hello.output"
。
事件类型
您可以通过 JavaScript 方法 addEventListener 侦听通常能够附加的任何事件。 例如,您可以监听单击按钮、提交表单或更改输入的时间。
要监听window
或document
事件(例如调整大小或用户离线),您需要将“@window”或“@document”附加到event
类型(例如resize@window->console#logEvent
将调用调整窗口大小时console
控制器上的函数logEvent
)。
有一种附加常见事件的速记方法,您可以在其中省略事件类型,并且它具有元素类型的默认操作。 但是,我强烈反对使用事件速记,因为它会增加不太熟悉 Stimulus 的人需要对您的代码做出的假设量。
在同一元素中使用多个控制器
很多时候,您可能希望将两段逻辑分解为单独的类,但要让它们在 HTML 中彼此接近。 Stimulus 允许您通过在 HTML 中放置对这两个类的引用来将元素连接到多个类。
在上面的示例中,我设置了一个basket
对象,它只关心计算篮子中的物品总数,还添加了一个child
对象,显示每件物品的袋子数量。
将数据传递给您的对象
Stimulus 在控制器类中提供了this.data.get
和this.data.set
方法,这将允许您更改与标识符在同一命名空间内的数据属性。 我的意思是,如果您想将数据从 HTML 传递到刺激控制器,只需将data-[identifier]-a-variable
类的属性添加到您的 HTML 元素。
调用this.data.set
时,它将更新 HTML 中的值,以便您在使用浏览器开发工具检查元素时看到值的变化。
使用命名空间数据属性是一种非常好的方法,可以帮助明确哪个数据属性适用于哪段代码。
初始化、连接、断开
随着应用程序的增长,您可能需要连接到“生命周期事件”来设置默认值、获取数据或处理实时通信。 Stimulus 有三个内置方法,它们在 Stimulus 类的整个生命周期中被调用。
当 Stimulus 看到具有匹配data-controller
属性的元素时,它将创建一个新版本的控制器并调用initialize
函数。 这通常会在您第一次加载页面时运行,但如果您要将新的 HTML 附加到包含对您的控制器的引用的页面(例如通过 AJAX),也会运行。 当您将元素移动到 DOM 中的新位置时,它不会运行。
在一个类被初始化后,Stimulus 会将它连接到 HTML 元素并调用connect
函数。 如果您要在 DOM 中移动元素,它也会调用connect
。 因此,如果您要获取一个元素,将其从一个元素中删除,然后将其附加到其他位置,您会注意到只会调用connect
。
当您从页面中删除一个元素时, disconnect
功能将运行,例如,如果您要替换 HTML 的正文,您可以删除任何可能需要重新运行的代码,如果该元素不在相同的位置。 例如,如果您有一个花哨的 WYSIWYG 编辑器,它向元素添加了大量额外的 HTML,您可以在调用disconnect
时将其恢复为原始状态。
继承功能
有时,您可能希望在 Stimulus 控制器之间共享一些通用功能。 Stimulus 很酷的一点是(在底层)您将一些普通的 JavaScript 类连接到 HTML 元素,因此共享功能应该很熟悉。
在此示例中,我设置了一个名为ParentController
的父类,然后由一个名为ChildController
的子类对其进行扩展。 这让我可以从ParentController
继承方法,因此我不必在ChildController
中复制代码。
在生产中使用它
我在上面演示了如何使用 Stimulus 的一些相当独立的示例,这些示例应该让您了解可以实现的目标。 我还认为我应该谈谈我如何在生产中使用它以及它对我的效果如何。
网页包
如果你使用的是 Webpack,那你就大饱眼福了! Stimulus 完全可以与 Webpack 一起使用。 他们的文档甚至有一个可爱的 Webpack 入门工具包。 它允许您将控制器分成单独的文件,Stimulus 将决定使用正确的名称作为标识符。
如果您想使用 Stimulus,则不必使用 webpack,但它可以清理大量体验。 就个人而言,Stimulus 是帮助我了解 Webpack 并真正感受到它提供的价值的库。
文件名约定
我在本文的介绍中提到我喜欢使用 Stimulus,因为它感觉井井有条。 当您将它与 Webpack 结合使用时,这一点真的很明显,它可以自动加载和注册控制器。
在 Webpack 中设置 Stimulus 后,它会鼓励您将文件命名为[identifier]_controller.js
,其中标识符是您将传递给 HTML data-controller
内容。
随着项目的增长,您可能还希望将 Stimulus 控制器移动到子文件夹中。 以一种神奇的方式,Stimulus 会将下划线转换为破折号,并将文件夹正斜杠转换为两个破折号,这将成为您的标识符。 例如,文件名chat/conversation_item_controller.js
将具有标识符chat--conversation-item
。
维护更少的 JavaScript
我最喜欢的一句话是“最好的代码就是没有代码”,我尝试将这种方法应用于我的所有项目。
Web 浏览器正在发生很大的变化,我非常相信,我今天需要编写 JavaScript 的大部分内容将在未来 5 年内标准化并融入浏览器。 一个很好的例子是 details 元素,当我第一次开始开发时,必须使用 jQuery 手动编写该功能是非常普遍的。
因此,如果我能用少量的 JavaScript 编写可访问的 HTML 来满足我的需求,并且抱着“这在今天可以完成工作,但在 5 年内我想轻松替换它”的心态,我会很高兴开发商。 当您开始编写更少的代码时,这是更容易实现的,而 Stimulus 正是这样做的。
首先是 HTML,然后是 JavaScript
我真正喜欢 Stimulus 鼓励的方法的一个方面是,我可以专注于将 HTML 通过网络发送给我的用户,然后使用 JavaScript 让这些内容更加活跃。
我一直喜欢利用用户注意力的前几毫秒来获取我必须与他们分享的内容——在他们面前。 然后担心在用户可以开始处理他们所看到的内容时设置交互层。
此外,如果 JavaScript 由于某种原因失败,用户仍然可以在没有 JavaScript 的情况下看到内容并与之交互。 例如,不是通过 AJAX 提交表单,而是通过重新加载页面的传统表单请求提交。
结论
我喜欢构建只需要少量可维护的 JavaScript 来增强用户体验的网站,有时构建一些感觉更简单的东西会很好。 有一些轻量级的东西很棒,我真的很喜欢没有太多的认知负担,它很清楚如何组织你的文件,并设置小面包屑来暗示 JavaScript 将如何与一段 HTML 一起运行。
我真的很喜欢与 Stimulus 一起工作。 它没有太多内容,因此学习曲线相当温和。 我非常有信心,如果我将我的代码传递给其他人,他们将成为快乐的开发人员。 我强烈建议尝试一下,即使只是出于好奇。
房间里的大象是它与 React 和 Vue 相比如何叠加,但在我看来,它们是满足不同需求的不同工具。 就我而言,我经常从我的服务器渲染出 HTML,并添加了一些 JavaScript 来改善体验。 如果我正在做一些更复杂的事情,我会考虑一种不同的方法(或推迟要求以帮助保持我的代码简单)。
延伸阅读
- 刺激主页
他们有一本很棒的手册,其中更深入地介绍了我上面概述的概念。 - 刺激 GitHub 存储库
通过探索 Stimulus 的代码,我学到了很多关于 Stimulus 的工作原理。 - 刺激备忘单
该手册在单页上进行了总结。 - 刺激论坛
看到其他人使用 Stimulus 让我真的觉得它正在被野外使用。