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>