现代框架大多数是先生成一个空的页面,而后经过特定的模板语言将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)
}
复制代码