svelte:如何在我自己的组件中使用事件修饰符
svelte: how to use event modifiers in my own components
我想开发自己的 Button 组件并能够处理事件修饰符,如下所示:
<MyButton on:click|preventDefault={handler}>Click me</MyButton>
但我收到以下错误:
Event modifiers other than 'once' can only be used on DOM elementssvelte(invalid-event-modifier)
在 MyButton 中,我可以像这样传递 on:click 事件:
<button on:click|preventDefault>
<slot />
</button>
但是如果没有 preventDefault
,我将无法使用 MyButton
所以另一种选择是有选择地传递事件修饰符,做这样的事情:
<MyButton preventDefault on:click={handler}>Click me</MyButton>
然后在 MyButton.svelte 中进行类似这样的操作(我知道这行不通)以选择性地应用事件修饰符。
<script>
export let prevenDefault=false
</script>
<button on:click|{preventDefault ? 'preventDefault' : ''}={handler}>Click me</MyButton>
知道如何处理吗?
我认为有两种方式适用:
- 防止事件回调中的默认值(更简单的方法)
- 通过传入 prop 防止默认(您的建议)
防止事件回调中出现默认值
Pros
Cons
Easier & cleaner to implement
Consumers of the component will have to call Event#preventDefault
imperatively
要进行此设置,您需要两件事。
- 要转发其事件的
<Button>
组件:
<script>
// Button.svelte
</script>
<!-- Note that we're not providing any callback, which forwards it -->
<button on:click>
<slot />
</button>
- 要在事件上调用
Event#preventDefault
的父组件:
<script>
// App.svelte
import Button from './Button.svelte';
</script>
<Button
on:click={(event) => {
event.preventDefault();
// your code here
}}
>
Click Me!
</Button>
通过传入 prop 来防止默认
Pros
Cons
Declaratively add event modifier
Consumers of the component will unwrap the original Event
object from CustomEvent#detail
这里你还需要两件事。
<Button>
组件在 <script>
标签中手动添加回调
<script>
// Button.svelte
import {
onMount,
onDestroy,
createEventDispatcher,
} from 'svelte';
export let preventDefault = false;
let button;
const dispatch = createEventDispatcher();
onMount(() => {
button.addEventListener('click', onClick);
});
onDestroy(() => {
button.removeEventListener('click', onClick);
});
function onClick(event) {
if (preventDefault) event.preventDefault();
dispatch('click', event);
}
</script>
<button bind:this={button}>
<slot />
</button>
- 传递给
preventDefault
属性的父组件
<script>
// App.svelte
import Button from './Button.svelte';
</script>
<Button
preventDefault
on:click={({ detail: event }) => {
// your code here
})
>
Click me!
</Button>
我想开发自己的 Button 组件并能够处理事件修饰符,如下所示:
<MyButton on:click|preventDefault={handler}>Click me</MyButton>
但我收到以下错误:
Event modifiers other than 'once' can only be used on DOM elementssvelte(invalid-event-modifier)
在 MyButton 中,我可以像这样传递 on:click 事件:
<button on:click|preventDefault>
<slot />
</button>
但是如果没有 preventDefault
,我将无法使用 MyButton所以另一种选择是有选择地传递事件修饰符,做这样的事情:
<MyButton preventDefault on:click={handler}>Click me</MyButton>
然后在 MyButton.svelte 中进行类似这样的操作(我知道这行不通)以选择性地应用事件修饰符。
<script>
export let prevenDefault=false
</script>
<button on:click|{preventDefault ? 'preventDefault' : ''}={handler}>Click me</MyButton>
知道如何处理吗?
我认为有两种方式适用:
- 防止事件回调中的默认值(更简单的方法)
- 通过传入 prop 防止默认(您的建议)
防止事件回调中出现默认值
Pros | Cons |
---|---|
Easier & cleaner to implement | Consumers of the component will have to call Event#preventDefault imperatively |
要进行此设置,您需要两件事。
- 要转发其事件的
<Button>
组件:
<script>
// Button.svelte
</script>
<!-- Note that we're not providing any callback, which forwards it -->
<button on:click>
<slot />
</button>
- 要在事件上调用
Event#preventDefault
的父组件:
<script>
// App.svelte
import Button from './Button.svelte';
</script>
<Button
on:click={(event) => {
event.preventDefault();
// your code here
}}
>
Click Me!
</Button>
通过传入 prop 来防止默认
Pros | Cons |
---|---|
Declaratively add event modifier | Consumers of the component will unwrap the original Event object from CustomEvent#detail |
这里你还需要两件事。
<Button>
组件在<script>
标签中手动添加回调
<script>
// Button.svelte
import {
onMount,
onDestroy,
createEventDispatcher,
} from 'svelte';
export let preventDefault = false;
let button;
const dispatch = createEventDispatcher();
onMount(() => {
button.addEventListener('click', onClick);
});
onDestroy(() => {
button.removeEventListener('click', onClick);
});
function onClick(event) {
if (preventDefault) event.preventDefault();
dispatch('click', event);
}
</script>
<button bind:this={button}>
<slot />
</button>
- 传递给
preventDefault
属性的父组件
<script>
// App.svelte
import Button from './Button.svelte';
</script>
<Button
preventDefault
on:click={({ detail: event }) => {
// your code here
})
>
Click me!
</Button>