StimulusBundle:Symfony 與 Stimulus 的整合
提示
在 https://ux.symfony.com 查看 Symfony UX 的即時示範!
此套件增加了 Symfony、Stimulus 和 Symfony UX 套件之間的整合
- Twig
stimulus_
函式與過濾器,用於新增 Stimulus 控制器、 - 在您的模板中新增動作與目標;
- Twig
- 整合載入 UX 套件(額外的 Stimulus 控制器)
安裝
首先,如果您還沒有資產處理系統,請選擇並安裝一個;兩者都與 StimulusBundle 完美搭配
- AssetMapper:基於 PHP 的資產處理系統
或
- Webpack Encore:基於 Node.js 的打包系統
請參閱 Encore 與 AssetMapper 的比較,以了解哪一個最適合您的專案。
下一步,安裝此套件
1
$ composer require symfony/stimulus-bundle
如果您使用 Symfony Flex,就完成了!Recipe 將會更新必要的檔案。如果沒有使用 Flex,或者您對手動設定感到好奇,請參閱手動設定。
提示
如果您使用 Encore,請務必安裝您的資產(例如 npm install
)並重新啟動 Encore。
用法
現在您可以在 assets/controllers
目錄中建立自訂的 Stimulus 控制器。實際上,您應該已經在那裡看到一個範例控制器:hello_controller.js
1 2 3 4 5 6 7
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
}
}
然後,在您的 HTML 中啟用控制器
1 2 3
<div data-controller="hello">
...
</div>
或者,此套件有一個 Twig 函式可以渲染屬性
1 2 3 4 5 6 7 8
<div {{ stimulus_controller('hello') }}>
...
</div>
<!-- would render -->
<div data-controller="hello">
...
</div>
就是這樣!每當此元素出現在頁面上時,hello
控制器就會啟動。
關於 Stimulus 還有很多東西要學習。請參閱 Stimulus 文件以了解所有好東西。
TypeScript 控制器
如果您想使用 TypeScript 來定義您的控制器,您可以!安裝並設定 sensiolabs/typescript-bundle。然後務必將 assets/controllers
路徑新增至 sensiolabs_typescript.source_dir
設定中。最後,在該目錄中建立您的控制器,就完成了。
UX 套件
Symfony 提供了一組 UX 套件,它們增加了額外的 Stimulus 控制器以解決常見問題。StimulusBundle 會啟用 assets/controllers.json
檔案中提及的任何第三方 Stimulus 控制器。每當您安裝 UX 套件時,此檔案都會更新。
官方 UX 套件包括
- ux-autocomplete:將
EntityType
、ChoiceType
或任何<select>
元素轉換為 Ajax 驅動的自動完成欄位(請參閱示範) - ux-chartjs:使用 Chart.js 輕鬆繪製圖表(請參閱示範)
- ux-cropperjs:用於裁切影像的表單類型和工具(請參閱示範)
- ux-dropzone:用於檔案上傳的樣式化「拖放區」表單類型(請參閱示範)
- ux-lazy-image:使用 BlurHash 優化影像載入(請參閱示範)
- ux-live-component:以零 JavaScript 建立動態介面(請參閱示範)
- ux-notify:使用 Mercure 發送伺服器發送的原生通知(請參閱示範)
- ux-react:從 Twig 渲染 React 組件(請參閱示範)
- ux-svelte:從 Twig 渲染 Svelte 組件(請參閱示範)
- ux-swup:與 Swup 整合(請參閱示範)
- ux-toggle-password:切換密碼輸入的可見性(請參閱示範)
- ux-translator:在 JavaScript 中使用您的 Symfony 翻譯(請參閱示範)
- ux-turbo:與 Turbo Drive 整合,以獲得單頁應用程式體驗(請參閱示範)
- ux-twig-component:建立由 PHP 類別支援的 Twig 組件(請參閱示範)
- ux-typed:與 Typed 整合(請參閱示範)
- ux-vue:從 Twig 渲染 Vue 組件(請參閱示範)
延遲載入 Stimulus 控制器
預設情況下,您的所有控制器(即 assets/controllers/
中的檔案 + assets/controllers.json
中的控制器)都會在每個頁面下載並載入。
有時您可能會有一個控制器僅在某些頁面上使用。在這種情況下,您可以將控制器設定為「延遲載入」。在這種情況下,控制器在初始頁面載入時不會被下載。相反地,一旦頁面上出現與控制器匹配的元素(例如 <div data-controller="hello">
),控制器以及它導入的任何其他內容都將透過 Ajax 延遲載入。
若要將您的自訂控制器設定為延遲載入,請在頂端新增一個特殊註解
1 2 3 4 5 6
import { Controller } from '@hotwired/stimulus';
/* stimulusFetch: 'lazy' */
export default class extends Controller {
// ...
}
若要將第三方控制器設定為延遲載入,請在 assets/controllers.json
中將 fetch
設定為 lazy
。
注意
如果您使用 TypeScript 撰寫控制器,且您使用的是 StimulusBundle ≤ 2.21.0,請確保在您的 TypeScript 設定中,removeComments
未設定為 true
。
世界各地的 Stimulus 工具
由於 Stimulus 被 Symfony 以外的開發人員使用,因此除了 UX 套件之外,還存在許多工具
- stimulus-use:為您的 Stimulus 控制器新增可組合的行為,例如去抖動、偵測外部點擊以及許多其他功能。
- stimulus-components:大量預先製作的 Stimulus 控制器,例如用於複製到剪貼簿、排序、彈出視窗(類似於工具提示)等等。
Stimulus Twig 輔助工具
此套件新增了一些 Twig 函式/過濾器,以協助在您的模板中新增 Stimulus 控制器、動作和目標。
注意
雖然此套件提供了這些有用的 Twig 函式/過濾器,但建議改用原始資料屬性,因為它們更直接。
提示
如果您使用 PhpStorm IDE,您可能需要安裝 Stimulus 外掛程式,以獲得屬性的良好自動完成功能。
stimulus_controller
此套件附帶一個特殊的 stimulus_controller()
Twig 函式,可用於渲染 Stimulus 控制器與值 以及 CSS 類別。Stimulus 控制器也可以透過使用 Outlets 引用其他控制器。
例如
1 2 3 4 5 6 7 8 9 10 11 12
<div {{ stimulus_controller('chart', { 'name': 'Likes', 'data': [1, 2, 3, 4] }) }}>
Hello
</div>
<!-- would render -->
<div
data-controller="chart"
data-chart-name-value="Likes"
data-chart-data-value="[1,2,3,4]"
>
Hello
</div>
如果您想要設定 CSS 類別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<div {{ stimulus_controller('chart', { 'name': 'Likes', 'data': [1, 2, 3, 4] }, { 'loading': 'spinner' }) }}>
Hello
</div>
<!-- would render -->
<div
data-controller="chart"
data-chart-name-value="Likes"
data-chart-data-value="[1,2,3,4]"
data-chart-loading-class="spinner"
>
Hello
</div>
<!-- or without values -->
<div {{ stimulus_controller('chart', controllerClasses = { 'loading': 'spinner' }) }}>
Hello
</div>
以及使用 outlets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<div {{ stimulus_controller('chart', { 'name': 'Likes', 'data': [1, 2, 3, 4] }, { 'loading': 'spinner' }, { 'other': '.target' ) }}>
Hello
</div>
<!-- would render -->
<div
data-controller="chart"
data-chart-name-value="Likes"
data-chart-data-value="[1,2,3,4]"
data-chart-loading-class="spinner"
data-chart-other-outlet=".target"
>
Hello
</div>
<!-- or without values/classes -->
<div {{ stimulus_controller('chart', controllerOutlets = { 'other': '.target' }) }}>
Hello
</div>
任何非純量值(例如 data: [1, 2, 3, 4]
)都會進行 JSON 編碼。並且所有值都會被正確逸出(字串 [
是一個逸出的 [
字元,因此屬性實際上是 [1,2,3,4]
)。
如果您在同一個元素上有多個控制器,您可以將它們串聯起來,因為還有一個 stimulus_controller
過濾器
1 2 3 4 5 6 7 8
<div {{ stimulus_controller('chart', { 'name': 'Likes' })|stimulus_controller('other-controller') }}>
Hello
</div>
<!-- would render -->
<div data-controller="chart other-controller" data-chart-name-value="Likes">
Hello
</div>
您也可以將產生的屬性作為陣列檢索,這對於表單等情況可能很有用
1
{{ form_start(form, { attr: stimulus_controller('chart', { 'name': 'Likes' }).toArray() }) }}
stimulus_action
stimulus_action()
Twig 函式可用於渲染 Stimulus 動作。
例如
1 2 3 4 5 6
<div {{ stimulus_action('controller', 'method') }}>Hello</div>
<div {{ stimulus_action('controller', 'method', 'click') }}>Hello</div>
<!-- would render -->
<div data-action="controller#method">Hello</div>
<div data-action="click->controller#method">Hello</div>
如果您在同一個元素上有多個動作和/或方法,您可以將它們串聯起來,因為還有一個 stimulus_action
過濾器
1 2 3 4 5 6 7 8
<div {{ stimulus_action('controller', 'method')|stimulus_action('other-controller', 'test') }}>
Hello
</div>
<!-- would render -->
<div data-action="controller#method other-controller#test">
Hello
</div>
您也可以將產生的屬性作為陣列檢索,這對於表單等情況可能很有用
1
{{ form_row(form.password, { attr: stimulus_action('hello-controller', 'checkPasswordStrength').toArray() }) }}
您也可以將參數傳遞給動作
1 2 3 4
<div {{ stimulus_action('hello-controller', 'method', 'click', { 'count': 3 }) }}>Hello</div>
<!-- would render -->
<div data-action="click->hello-controller#method" data-hello-controller-count-param="3">Hello</div>
stimulus_target
stimulus_target()
Twig 函式可用於渲染 Stimulus 目標。
例如
1 2 3 4 5 6
<div {{ stimulus_target('controller', 'myTarget') }}>Hello</div>
<div {{ stimulus_target('controller', 'myTarget secondTarget') }}>Hello</div>
<!-- would render -->
<div data-controller-target="myTarget">Hello</div>
<div data-controller-target="myTarget secondTarget">Hello</div>
如果您在同一個元素上有多個目標,您可以將它們串聯起來,因為還有一個 stimulus_target
過濾器
1 2 3 4 5 6 7 8
<div {{ stimulus_target('controller', 'myTarget')|stimulus_target('other-controller', 'anotherTarget') }}>
Hello
</div>
<!-- would render -->
<div data-controller-target="myTarget" data-other-controller-target="anotherTarget">
Hello
</div>
您也可以將產生的屬性作為陣列檢索,這對於表單等情況可能很有用
1
{{ form_row(form.password, { attr: stimulus_target('hello-controller', 'myTarget').toArray() }) }}
設定
如果您使用 AssetMapper,您可以設定控制器目錄的路徑和 controllers.json
檔案的路徑,如果需要使用不同的路徑的話
1 2 3 4 5 6
# config/packages/stimulus.yaml
stimulus:
# the default values
controller_paths:
- '%kernel.project_dir%/assets/controllers'
controllers_json: '%kernel.project_dir%/assets/controllers.json'
手動安裝細節
當您安裝此套件時,其 Flex recipe 應該會處理更新所有需要的檔案。如果您未使用 Flex 或想要再次檢查變更,請查看 StimulusBundle Flex recipe。以下是其中內容的摘要
assets/bootstrap.js
啟動 Stimulus 應用程式並載入您的控制器。它由assets/app.js
導入,其確切內容取決於您是否安裝了 Webpack Encore 或 AssetMapper(請參閱下方)。assets/app.js
已更新為導入assets/bootstrap.js
assets/controllers.json
:此檔案開始時(大部分)是空的,並且會在您安裝提供 Stimulus 控制器的 UX 套件時自動更新。assets/controllers/
:此目錄是您應該放置自訂 Stimulus 控制器的地方。它附帶一個範例hello_controller.js
檔案。
其他一些變更取決於您使用的資產系統
使用 AssetMapper
如果您使用 AssetMapper,則會將兩個新條目新增至您的 importmap.php
檔案
1 2 3 4 5 6 7 8 9 10 11
// importmap.php
return [
// ...
'@symfony/stimulus-bundle' => [
'path' => '@symfony/stimulus-bundle/loader.js',
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
];
Recipe 將會更新您的 assets/bootstrap.js
檔案,使其看起來像這樣
1 2 3 4
// assets/bootstrap.js
import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp();
@symfony/stimulus-bundle
指的是您 importmap.php
檔案中的新條目之一。此檔案由套件動態建立,並將導入您的所有自訂控制器以及 controllers.json
中的控制器。當您的應用程式在偵錯模式下執行時,它還將動態啟用 Stimulus 中的「debug」模式。
提示
僅針對 AssetMapper 6.3,您還需要在 base.html.twig
中加入 {{ ux_controller_link_tags() }}
。AssetMapper 6.4+ 中則不需要。
使用 WebpackEncoreBundle
如果您使用 Webpack Encore,recipe 也會更新您的 webpack.config.js
檔案以包含此行
1 2
// webpack.config.js
.enableStimulusBridge('./assets/controllers.json')
assets/bootstrap.js
檔案將會更新,使其看起來像這樣
1 2 3 4 5 6 7 8 9
// assets/bootstrap.js
import { startStimulusApp } from '@symfony/stimulus-bridge';
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export const app = startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
true,
/\.[jt]sx?$/
));
並且 2 個新套件 - @hotwired/stimulus
和 @symfony/stimulus-bridge
- 將會新增至您的 package.json
檔案。
Stimulus 控制器是如何載入的?
當您安裝 UX PHP 套件時,Symfony Flex 將會自動更新您的 package.json
檔案(如果使用 AssetMapper,則不需要或不會執行此操作),以指向位於該 PHP 套件內的「虛擬套件」。例如
1 2 3 4 5 6
{
"devDependencies": {
"...": "",
"@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/assets"
}
}
這為您提供了一個真正的 Node 套件(例如 @symfony/ux-chartjs
),它不是被下載,而是直接指向已經存在於您的 vendor/
目錄中的檔案。
Flex 指令通常也會更新您的 assets/controllers.json
檔案,以將新的 Stimulus 控制器新增至您的應用程式。例如:
1 2 3 4 5 6 7 8 9 10 11
{
"controllers": {
"@symfony/ux-chartjs": {
"chart": {
"enabled": true,
"fetch": "eager"
}
}
},
"entrypoints": []
}
最後,您的 assets/bootstrap.js
檔案將自動註冊
assets/controllers/
中的所有檔案作為 Stimulus 控制器;- 以及
assets/controllers.json
中描述的所有控制器作為 Stimulus 控制器。
注意
如果您使用 WebpackEncore,bootstrap.js
檔案會與 @symfony/stimulus-bridge 協同運作。若使用 AssetMapper,bootstrap.js
檔案會直接與此套件組搭配運作:@symfony/stimulus-bundle
條目會透過 Flex 新增至您的 importmap.php
檔案,該條目指向一個動態建置的檔案,以尋找並載入您的控制器(請參閱設定)。
最終結果:您安裝一個套件,然後立即擁有可用的 Stimulus 控制器!在此範例中,它稱為 @symfony/ux-chartjs/chart
。嗯,嚴格來說,它會被稱為 symfony--ux-chartjs--chart
。但是,您可以將原始名稱傳遞到 WebpackEncoreBundle 的 {{ stimulus_controller() }}
函式中,它會將其正規化
1 2 3 4
<div {{ stimulus_controller('@symfony/ux-chartjs/chart') }}>
<!-- will render as: -->
<div data-controller="symfony--ux-chartjs--chart">