如何将参数传递到:单击Svelte



将函数绑定到按钮既简单又直接:

<button on:click={handleClick}>
Clicks are handled by the handleClick function!
</button>

但是,当我这样做时,我看不到向函数传递参数(自变量)的方法:

<button on:click={handleClick("parameter1")}>
Oh no!
</button>

该函数在页面加载时被调用,以后再也不会调用。

是否可以将参数传递给从on:click{}调用的函数?


编辑:

我刚刚发现是一种很有技巧的方法(见评论)。从内联处理程序调用函数是有效的。

<button on:click={() => handleClick("parameter1")}>
It works...
</button>

TL;DR

只需将处理程序函数包装到另一个函数中即可。要优美,请使用箭头功能。


您必须使用函数声明,然后用参数调用处理程序。箭头功能非常优雅,适合这种情况。

为什么我需要另一个函数包装器

如果只使用处理程序并传递参数,它会是什么样子?

可能是这样的:

<button on:click={handleClick("arg1")}>My awesome button</button>

但请记住,handleClick("arg1")这就是你立即调用函数的方式,这正是你这样说时发生的事情,当执行到达这一行时,它将被调用,而并不像预期的那样,ON BUTTON CLICK

因此,您需要一个函数声明,它将仅由单击事件调用,并且在函数声明中,您可以使用任意多的参数调用处理程序。

<button on:click={() => handleClick("arg1", "arg2")}>
My awesome button
</button>

正如@Rich Harris(Svelte的作者)在上述评论中指出的那样:这不是黑客攻击,但文档在教程中也显示了这一点:https://svelte.dev/tutorial/inline-handlers

Rich在评论中回答了这个问题,这要归功于他,但在点击处理程序中绑定参数的方法如下:

<a href="#" on:click|preventDefault={() => onDelete(projectId)}>delete</a>
<script>
function onDelete (id) {
...
}
</script>

为了给同样有困难的人提供一些额外的细节,如果没有,它应该在文档中,你也可以在这样的处理程序中获得点击事件:

<a href="#" on:click={event => onDelete(event)}>delete</a>
<script>
function onDelete (event) {
// if it's a custom event you can get the properties passed to it:
const customEventData = event.detail
// if you want the element, you guessed it:
const targetElement = event.target
...
}
</script>

Svelte文档/教程:内联处理程序

文档中没有提到明确的方法,您的解决方案可以工作,但确实不是很优雅。我自己的首选解决方案是在脚本块本身中使用currying

const handleClick = (parameter) => () => {
// actual function
} 

在HTML 中

<button on:click={handleClick('parameter1')>
It works...
</button>

小心欺骗

正如评论中所提到的,咖喱有其陷阱。在上面的示例中,最常见的是handleClick('parameter1')在单击时不会被激发,而是在渲染时被激发,返回一个函数,该函数将在单击时被激发。这意味着此函数将始终使用"parameter1"作为其参数。

因此,只有当使用的参数是某种常量并且在渲染后不会更改时,使用此方法才是安全的。

这会让我想到另一个问题:

1) 如果它是一个使用参数的常数,你也可以使用一个单独的函数

const handleParameter1Click = () => handleClick('parameter1');

2) 如果该值是动态的,但在组件中可用,则仍然可以使用独立的函数来处理:

let parameter1;
const handleParameter1Click = () => handleClick(parameter1);

3) 如果该值是动态的,但不能从组件中获得,因为这取决于某种范围(例如:在#每个块中呈现的项目列表),则"hacky">方法会更好地工作。然而,我认为在这种情况下,最好将列表元素本身作为一个组件,并返回到案例#2

总结:咖喱在某些情况下会起作用,但除非你非常清楚并小心地使用它,否则不建议使用。

我用这个来处理它:

<a href="#" on:click|preventDefault={onDelete.bind(this, project_id)}>delete</a>
function onDelete(id) {
}

Pug溶液

!=分配。是,使用!=进行分配。真奇怪。示例Foo(on:click!='{() => click(i)}')。这是根据svelte预处理(在pug中包含模板的必要的transiler)的文档:

Pug将元素属性内的所有内容编码为html实体,因此attr="{foo && bar}"变为attr="foo &amp;&amp; bar"。为了防止这种情况发生,不要使用=运算符,而是使用不会对属性值[…]进行编码的!=。这对于传递回调也是必要的。

就我个人而言,我将为此使用util函数,因为用!=赋值太麻烦了。

// util fn
const will = (f, v) => () => f(v);
// in pug template we can again assign with =
Foo(on:click='{will(click, i)}')

这里有一个去抖动方法和事件参数:

<input type="text" on:keydown={event => onKeyDown(event)} />

const onKeyDown = debounce(handleInput, 250);
async function handleInput(event){
console.log(event);
}

有尸检风险,请检查https://svelte.dev/repl/08aca4e5d75e4ba7b8b05680f3d3bf7a?version=3.23.1

可排序的表格。请注意,参数以一种神奇的方式传递给标题点击处理功能。不知道为什么会这样。也许是自动咖喱?

我使用的是:

{#each data as item}    
<li on:click={handle(item)}>{item.name}</li>
{/each}

并且它在渲染时没有运行该函数,而是在单击时工作。

很抱歉坏死,但它似乎在这种特殊情况下有效。我不知道为什么,但我认为这是相关的,因为即使是Rich也说不应该。经过搜索,我找不到任何使这个案子独一无二的原因。

REPL-

相关内容

  • 没有找到相关文章

最新更新