我建议在可行的情况下避免使用范围过大的控制器。拥有带有多个控制器的大部分 DOM 可能会带来一些性能问题。
拥有sidebar 和sidebar-toggle 控制器的另一种方法是使用通用的“触发事件”控制器。
我们甚至可以从 Alpine.js 及其x-on directive 中获得灵感。我们可以有一个较小范围的“on”动作来做一些类型控制器,让我们有一种通用的方式来触发任何事件。
HTML
让我们从 HTML 开始,类似于前面的答案,我们有一个侧边栏 div,然后是两个按钮,它们的作用基本相同(触发事件)。
我们可以利用 Stimulus 的方法来协调 DOM 事件来帮助我们,但这次使用名为 'sidebar:toggle' 的自定义全局事件。
请注意,侧边栏控制器使用@window 侦听事件,以确保它在 DOM 中一直拾取任何“冒泡”事件。
https://stimulus.hotwired.dev/reference/controllers#cross-controller-coordination-with-events
<body>
<header class="sm:hidden">
<button
data-controller="on"
data-action="click->on#go"
data-on-event-name-param="sidebar:toggle"
>
Toggle sidebar
</button>
</header>
<section data-controller="sidebar" data-action="sidebar-toggle@window->sidebar#layout">
Some content in the sidebar
</section>
<main>
<button
class="hidden sm:inline-block"
data-controller="on"
data-action="click->on#go"
data-on-event-name-param="sidebar:toggle"
>
Toggle sidebar
</button>
</main>
</body>
JavaScript(控制器)
Sidebar 控制器将拥有您想要的任何东西,而且还有一个 toggle 的方法,我们可以通过操作触发该方法。
import { Controller } from '@hotwired/stimulus';
class Sidebar extends Controller {
static targets = [];
static values = { expanded: { default: false, type: Boolean } };
connect() {
// do the things
}
toggle() {
this.expandedValue = !this.expandedValue;
}
}
On 控制器利用 Stimulus action parameters 能够接收在 DOM 上设置的任何动态值作为它的事件。
请注意,On 控制器故意使事件冒泡(这是默认设置,但最好是明确的),以便窗口上的任何其他事件侦听器都可以侦听。
import { Controller } from '@hotwired/stimulus';
class On extends Controller {
go({ params: { eventName } }) {
this.dispatch(eventName, { prefix: '', bubbles: true, cancelable: false });
}
}