DOM事件
在Svelte之中,我们如果要绑定DOM上的事件可以添加 on: 关键词进行监听。
<div on:mousemove={handleMousemove}>
这一点和vue很像,但在Svelte中可没有简写。
下面来看一个完整事例:
<script> let x = 0, y = 0 function handleMousemove(e) { x = e.clientX y = e.clientY } </script> <div on:mousemove={handleMousemove}> 鼠标的位置是: {x} x {y} </div> <style> div { width: 100%; height: 100vh; cursor: default; } </style>
预览
当然我们也可以这样写,官方叫这种方式为:内联声明事件处理
<div on:mousemove={e=>{x=e.clientX;y=e.clientY}}> 鼠标的位置是: {x} x {y} </div>
效果是一样的,加不加引号也无所谓
<div on:mousemove="{e=>{x=e.clientX;y=e.clientY}}">
对了值得一提的是在Svelte中你不用担心性能问题,怎么方便怎么来。(符合你需要的规范是前提)
事件修饰符
修饰符如名,给事件处理添加独立功能。
首先我们得知道有哪些事件修饰符:
修饰符 |
作用 |
preventDefault | 调用 event.preventDefault() ,在运行处理程序之前调用 |
stopPropagation | 调用 event.stopPropagation() ,防止事件到达下一个元素 |
passive | 优化了对 touch/wheel 事件的滚动表现(Svelte 会在合适的地方自动添加滚动条) |
nonpassive |
显式设置 passive: false |
capture |
在 capture 阶段而不是 bubbling 阶段触发事件处理程序 (可以简单理解触发父级元素,而不是子元素) |
once |
运行一次事件处理程序后将其删除 |
self |
仅当 event.target 是其本身时才执行 |
当然修饰符可以一起用 | 间隔开来。
下面来看一个案例
<div on:mousemove|once={e=>{x=e.clientX;y=e.clientY}}> 鼠标的位置是: {x} x {y} </div>
这样就只会触发一次了,再看一个案例
<button on:click|once|self={follower}> 关注 </button>
这样就可以多个修饰符一起用
组件事件
组件也可以调度事件。但是必须创建一个 event dispatcher,即组件内必须创建一个相同事件并在外部进行分配。
其实就像子组件给父组件事件。
在子组件内我们需要使用 createEventDispatcher function。
const dispatch = createEventDispatcher() 实例化不支持在 setTimeout 之类的事件回调之中使用)。
我们创建一个 Follower.svelte 组件:
<script> import { createEventDispatcher } from 'svelte' const dispatch = createEventDispatcher() let name = 'uiuing' function tellTip() { dispatch('tip', { name }) } </script> <button on:click={tellTip}>关注uiuing</button>
App.svelte
<script> import Follower from './Follower.svelte' </script> <Follower on:tip={e=>console.log(e.detail.name)}/>
点击之后预览
代码解读
on:tip tip为事件名称,e.detail 内容为子组件 dispatch 内容,dispatch('事件', 传递对象)
事件转发
其实事件转发很简单,其实就是组件嵌套的时候,我们把事件一层一层传递上去。
例如到 Follower 组件和 App 中间再嵌套一个 Send 组件
<script> import Follower from './Follower.svelte' import { createEventDispatcher } from 'svelte' const dispatch = createEventDispatcher() function send(e) { dispatch('tip', e.detail) } </script> <Follower on:tip={send} />
我们将获取到的数据往上传,你改变的只是function里接到 event 然后把 e.detail 原封不动传递上去。
如果我们需要把所有 tip 事件都转发呢?
直接简写就可以了
<script> import Follower from './Follower.svelte' </script> <Follower on:tip />
效果是一样的,贴上 App.svelte 的代码大家自己实验。
<script> import Send from './Send.svelte' </script> <Send on:tip={e=>console.log(e.detail.name)}/>
事件转发也适用于 DOM 事件
例如 on:click
App.svelte
<script> import Follower from './Follower.svelte' </script> <Follower on:click={()=>{console.log('关注成功!')}} />
Follower.svelte
<button>关注uiuing</button>
这样点击按钮是没有效果的
我们需要转发一下
Follower.svelte
<button on:click>关注uiuing</button>