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() 方法将事件转发。