Svelte 的 action 怎么传多个参数?
我在 Svelte 里写了一个自定义 action,想传两个参数进去,但不知道语法该怎么写。试了下直接传对象好像不行,控制台报错说函数接收的不是预期的类型。
比如在 Vue 里我可以这样写指令:
<div v-my-directive="{ delay: 200, immediate: true }"></div>
但在 Svelte 里用 use:myAction={{ delay: 200, immediate: true }} 却没生效,action 函数里拿到的参数是 undefined。到底该怎么正确传多个参数啊?
Svelte的action函数是这样定义的:
具体来说,如果你要传多个参数,有两种正确方式:
第一种是把参数包装成对象传进去(你试过但可能写法有问题):
注意这里的关键点:必须用双花括号,外层是Svelte的语法,内层是JavaScript对象。
第二种是直接传多个参数(适用于参数较少的情况):
然后在action里这样接收:
你遇到的问题可能是action函数定义方式不对。正确的action应该返回一个对象,包含可选的update和destroy方法。比如:
为什么这样做?因为Svelte的action设计就是这样:第一个参数总是DOM节点,第二个参数才是你传的值。当这个值变化时,会触发update回调。
顺便吐槽下,Svelte的文档有时候确实写得不够直观,这些细节得靠踩坑才知道... 我之前也是试了好久才发现要这样传参。
正确的写法是这样的:
注意是双花括号
{{ ... }},不是单花括号,也不是三花括号。Svelte 在编译时会把{{ ... }}解析成 JS 对象传给 action 函数。然后你的 action 函数定义应该是这样的:
function myAction(node, params) {
// 这里的 params 就是 { delay: 200, immediate: true }
const { delay = 100, immediate = false } = params;
// ...
}
别忘了 action 返回的销毁函数也接收这个 params,如果你需要的话:
function myAction(node, params) {
// 初始化逻辑
return {
update(newParams) {
// 比如 delay 变了需要重新计时
// 用 newParams 替换旧的 params
},
destroy() {
// 清理逻辑,也能拿到 params
}
};
}
如果还是 undefined,大概率是变量名写错了,比如把
params写成param,或者在组件里用了{}而不是{{}}。Svelte 的模板语法里,花括号是区分单双的,这点和 Vue 很像,但别搞混了。更好的写法是给 action 加个类型声明(如果你用 TypeScript 的话),这样 IDE 会自动提示参数结构,不容易写错:
function myAction(node: HTMLElement, params?: { delay?: number; immediate?: boolean }) {
// ...
}
这样写完之后,再传参就不会心里没底了。