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 讓我真的覺得它正在被野外使用。