Svelte 官方入门教程(5) - 事件
上一讲中,我们使用过on:click={toggle}
,今天咱们就详细讲解下事件。
一、DOM事件
来看个一例子:
1 |
|
正如我们上一讲中已经简要看到的,您可以使用 on: 指令,监听元素上的任何事件
二、内联事件
您还可以内联声明事件处理程序:
1 |
|
还是上面的例子,我们可以把事件采用内联的写法。
1 |
|
上面的on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}"
可以看到内联的事件写在了""
内,其实属性值上的双引号是可选
的,只是某些环境下有助于语法突出显示
。
在某些框架中,您可能会看到出于性能原因避免使用内联事件处理程序的建议,尤其是内部循环。 该建议不适用于 Svelte — 无论您选择哪种形式,编译器都会始终做正确的事情。
三、事件修饰符
DOM 事件处理程序具有额外的 修饰符(modifiers) 。 例如,带 once
修饰符的事件处理程序只运用一次:
1 |
|
通过上面的例子你不难发现事件修饰符的使用方式,事件|修饰符
。
下面列出所有的修饰符供大家参考:(所有的指的是当前版本下)
preventDefault
:调用event.preventDefault()
,在运行处理程序之前调用。比如,对客户端表单处理有用。stopPropagation
:调用event.stopPropagation()
, 防止事件影响到下一个元素。passive
: 优化了对touch/wheel
事件的滚动表现(Svelte
会在合适的地方自动添加滚动条)。capture
— 在capture
阶段而不是bubbling
阶段触发事件处理程序once
:运行一次事件处理程序后将其删除。self
— 仅当event.target
是其本身时才执行。trusted
— 仅当事件是由用户行为生成的时候,这个属性的值为 true,属性是一个只读属性。
你可以将修饰符组合在一起使用,例如:on:click|once|capture={...}
。
四、组件事件
组件也可以调度事件,为此,组件内必须创建一个相同事件并在外部进行分配。 更改 Inner.svelte
:
1 |
|
createEventDispatcher
必须在首次实例化组件时调用它,—组件本身不支持如 setTimeout 之类的事件回调。 定义一个dispatch
进行连接,进而把组件实例化。
然后我们把Inner
组件引入到App
组件中
1 |
|
请注意,由于 on:message
指令,App
组件正在侦听 Inner
组件发送的消息。 该指令是一个以 on:
为前缀的属性,后跟我们正在调度的事件名称(在本例中为message
)。
如果没有这个属性,消息仍然会被发送,但应用程序不会对其做出反应。 您可以尝试删除 on:message
属性并再次按下按钮。
您也可以尝试将事件名称更改为其他名称。 例如,将
Inner.svelte
中的dispatch('message')
更改为dispatch('myevent')
并将App.svelte
组件中的属性名称从on:message
更改为on:myevent
。
REPL
五、事件转发
与 DOM
事件不同, 组件事件不会 冒泡(bubble)
,如果你想要在某个深层嵌套的组件上监听事件,则中间组件必须 转发(forward)
该事件。
在这种情况下,我们具有与上一节相同的 App.svelte
和 Inner.svelte
,不过现在还需创建一个 Outer.svelte
,并且在 Outer.svelte
组件中添加 <Inner/>
。
解决这个问题的方法之一是添加 createEventDispatcher
到 Outer.svelte
中,监听其 message
事件,并为它创建一个转发程序:
Outer.svelte
1 |
|
但这样书写似乎有些臃肿,因此 Svelte 设立了一个简写属性 on:message。 message 没有赋予特定的值得情况下意味着转发所有massage事件:
但是这样要写很多重复的代码,所以Svelte
为我们提供了一个等效的简写方式 —— 一个没有值的 on:message
事件指令意味着“转发所有消息事件”
1 |
|
REPL
六、DOM事件转发
事件转发也是可以应用到标准的DOM事件上的。
看例子:
FancyButton
1 |
|
App
1 |
|
我们希望<FancyButton>
组件内部接收外部的handleClick()
,为此,我们只需要为FancyButton.svelte
内的<button>
标签添加click
事件即可:
1 |
|
总结
- 使用 on: 指令,例如 on:click,也可以直接内联一个函数的形式 on:click={ () => … },并且内联的不会有性能问题,还可以将函数提到外部的形式 on:click={ handler }。两者的结果没有什么区别。
- 支持绑定组件的自定义事件,组件需要使用 createEventDispatcher() 方法将事件转发。