将函数绑定到按钮既简单又直接:
<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 && 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-