現代框架大多數是先生成一個空的頁面,而後經過特定的模板語言將JSON轉換爲DOM元素來填充該頁面。而Stimulus並不會干擾HTML的建立,相反的,它是依附於現有HTML文檔的。Stimulus關注的重點是對現有DOM元素的操縱,而不是對DOM元素的建立。Stimulus+Turbolinks的結合會更適合「傳統前端」。html
本文只是針對用stimulus-start新建的項目。前端
先從git上面將stimulus
框架拖下來:git
$ git clone https://github.com/stimulusjs/stimulus-starter.git
$ cd stimulus-starter
複製代碼
安裝依賴,要使用yarn
:github
$ yarn install
複製代碼
運行項目:數組
$ yarn start
複製代碼
而後打開http://localhost:9000/
瀏覽器
stimulus是mvc框架。視圖在public
目錄下,控制器在src/controllers
目錄下。mvc
|- public
|-- *.html
|-- *.css
|- src
|-- controllers
|---- hello_controller.js
|-- index.js
複製代碼
${controllerIdentifier}_controller.js
,單詞間用下劃線_
鏈接;-
鏈接單詞。視圖中元素和控制器的buxia關聯都是由data
屬性來完成。框架
當Stimulus將控制器鏈接到元素時,該元素及其全部子元素構成控制器的範圍。ide
例如,<div>
及子元素<h1>
是控制器的範圍的一部分,但周邊<main>
元件是沒有的。
<main>
<div data-controller="reference">
<h1>Reference</h1>
</div>
</main>
複製代碼
用data-controller=${ controllerIdentifier }
指定控制器,將當前DOM塊和控制器綁定,單詞間用短橫線-
鏈接。
<div data-controller="hello">
<input type="text">
<button>Greet</button>
</div>
複製代碼
一個DOM綁定多個控制器的時候用空格分隔:
// 綁定clipboard和list-item兩個控制器
<div data-controller="clipboard list-item"></div>
複製代碼
一樣,多個DOM綁定相同的控制器也是很常見的:
<ul>
<li data-controller="list-item">One</li>
<li data-controller="list-item">Two</li>
<li data-controller="list-item">Three</li>
</ul>
複製代碼
這裏,每一個<li>
都有本身的list-item
控制器實例。
始終用駝峯命名。
export default class extends Controller {
// 註冊sayHi事件
sayHi() {
console.log("Hello, Stimulus!", this.element)
}
}
複製代碼
同原生js事件綁定的event參數同樣。
適用於全部事件的屬性:
屬性名 | 值 |
---|---|
event.type | 事件名稱(例如:'click' ) |
event.target | 觸發事件的元素(點擊的最內層元素) |
event.currentTarget | 監聽事件的元素(具備data-action 屬性的元素,document或者window) |
還可使用:
方法 | 結果 |
---|---|
event.preventDefault() | 取消事件的默認行爲 |
event.stopPropagation() | 取消冒泡 |
用data-action
爲DOM綁定事件。格式爲eventName->controllerIdentifier#method
。 好比,點擊按鈕的時候觸發hello
控制器裏面的sayHi
方法:
<div data-controller="hello">
<button data-action="click->hello#sayHi">click</button>
</div>
複製代碼
Stimulus規定click
是<button>
元素的默認事件,能夠省略click->
。
<div data-controller="hello">
<button data-action="hello#sayHi">click</button>
</div>
複製代碼
給元素綁定不少動做是很常見的,多個動做用空格分隔,Stimulus按照其描述符出現的順序從左到右調用動做:
<input type="text" data-action="focus->field#highlight input->search#update">
複製代碼
有時控制器須要監聽在全局window
或document
對象上分派的事件。 您能夠附加@window
或@document
在一個data-action
上通常監聽全局事件:
// 當在window上觸發click事件的時候,指定gallery控制器的layout方法
<div data-controller="gallery"
data-action="click@window->gallery#layout">
</div>
複製代碼
不一樣標籤的默認事件是不一樣的。
element | default event |
---|---|
a | click |
button | click |
form | submit |
input | change |
input[type="submit"] | click |
select | change |
textarea | change |
若是是爲一個<a>
標籤綁定click事件,也會觸發標籤的默認跳轉。這個時候能夠用event.preventDefault()
來取消默認行爲。
greet( event ) {
event.preventDefault()
}
複製代碼
生命週期回調方法容許在控制器鏈接到文檔和從文檔斷開鏈接時進行響應。
事件名 | 事件內容 |
---|---|
initialize | 當控制器首次實例化時執行一次 |
connect | 每當控制器鏈接到DOM時,都會調用該方法 |
disconnect | 每當控制器與DOM斷開鏈接時,都會調用該方法 |
當知足如下兩個條件時,控制器纔算鏈接到文檔:
document.documentElement
的子元素);data-controller
屬性中。當connect
兩個條件中的任意一個不知足時,將觸發disconnect
事件,例如在一下狀況:
data-controller
被刪除或修改;目標對應了頁面上特定的DOM元素,方便在方法中操做DOM元素或者拿到DOM元素的值。用${name}Target
獲取。
始終用駝峯命名。
使用static targets
數組在控制器類中定義目標名稱:
export default class extends Controller {
/* 聲明目標數組,只有在該數組中註冊了的目標纔是有效的 */
static targets = [ "name" ];
greet() {
/* this.nameTarget就是註冊的name目標對應的DOM元素 */
let element = this.nameTarget;
/* 取得目標的值 */
let name = element.value;
}
}
複製代碼
對於static targets
數組中定義的每一個目標名稱,Stimulus會將如下屬性添加到控制器,其中[name]
對應目標的名稱:
名稱 | 值 |
---|---|
this.[name]Target | 範圍中的第一個匹配目標 |
this.[name]Targets | 範圍內全部匹配目標的數組 |
this.has[Name]Target | 若是範圍內存在匹配的目標,返回true |
注意:當沒有匹配元素時,訪問this.[name]Target
將引起錯誤。
用data-target
來綁定目標,格式爲controllerIdentifier.targetName
。
<div data-controller="hello">
<input data-target="hello.name" type="text">
</div>
複製代碼
元素可能具備多個目標描述符,而且範圍中的多個元素共享相同的描述符是很常見的。多個目標用空格分隔。
<form data-controller="search checkbox">
<input type="checkbox" data-target="search.projects checkbox.input">
<input type="checkbox" data-target="search.messages checkbox.input">
</form>
複製代碼
在取得目標值得時候,this.nameTarget.value
的寫法在複用時略顯笨重,因此提供了目標的getter
來簡化操做。
export default class extends Controller {
greet() {
let name = this.name; // tom
this.name+=1; // tom1
}
get name() {
return this.nameTarget.value;
}
set name( value ) {
this.nameTarget.value = value;
}
}
複製代碼
若是要給控制器傳送一些自定義數據,能夠這樣作,在視圖中:
<div data-controller="slideshow" data-slideshow-index="1"></div>
複製代碼
在控制器中:
initialize() {
let index = this.element.getAttribute( 'data-slideshow-index' );
}
複製代碼
這樣作很繁瑣,因此Stimulus內置了data
對象來簡化操做。 每一個Stimulus控制器都有this.data
數據對象。數據對象是爲了方便地訪問data-controller
元素上的自定義屬性。
data-${controllerIdentifier}-${dataName}
。dataName
要用短橫線鏈接。this.data.get( dataName )
。dataName
要用駝峯寫法。在控制器裏面要取得上面的data-slideshow-index
就能夠這樣:
initialize() {
let index = this.data.get("index")
}
複製代碼
方法名 | 解釋 |
---|---|
has( dataName ) |
若是有指定屬性,返回true |
get( dataName ) |
返回指定屬性的值(字符串) |
set( dataName, value ) |
設置指定屬性的值 |
delete( dataName ) |
刪除指定屬性的值 |
在大量複用data的時候,能夠定義getter和setter來簡化操做。
get index() {
return this.data.get("index");
}
set index( value ) {
this.data.set("index", value)
}
複製代碼