通常,你需要附件依赖于某些参数或组件状态。在这种情况下,你可以使用 附件工厂 - 一个返回附件的函数。
¥Often, you need an attachment to depend on some parameters or component state. In this scenario, you can use an attachment factory — a function that returns an attachment.
在这个练习中,我们想使用 Tippy.js 库向 <button> 添加工具提示。附件已与 {@attach tooltip} 连接,但如果你将鼠标悬停在按钮上(或使用键盘将其聚焦),工具提示将不显示任何内容。
¥In this exercise, we want to add a tooltip to the <button> using the Tippy.js library. The attachment is already wired up with {@attach tooltip}, but if you hover over the button (or focus it with the keyboard) the tooltip contains no content.
首先,我们需要将简单的附件转换为返回附件的工厂函数。
¥First, we need to convert our simple attachment into a factory function that returns an attachment.
function tooltip(node) {
return (node) => {
const tooltip = tippy(node);
return tooltip.destroy;
};
}接下来,工厂需要接受我们想要传递给 Tippy 的选项(在本例中仅为 content):
¥Next, the factory needs to accept the options we want to pass to Tippy (in this case just content):
function tooltip(content) {
return (node) => {
const tooltip = tippy(node, { content });
return tooltip.destroy;
};
}
tooltip(content)表达式在 effect 内部运行,因此每当内容发生变化时,附件都会被销毁并重新创建。
最后,我们需要调用附件工厂,并在 {@attach} 标签中传递 content 参数:
¥Finally, we need to call the attachment factory and pass the content argument in our {@attach} tag:
<button {@attach tooltip(content)}>
Hover me
</button><script>
import tippy from 'tippy.js';
let content = $state('Hello!'); function tooltip(node) {const tooltip = tippy(node);
return tooltip.destroy;
}
</script>
<input bind:value={content} /><button {@attach tooltip}>Hover me
</button>
<style>
:global { [data-tippy-root] {--bg: #666;
background-color: var(--bg);
color: white;
border-radius: 0.2rem;
padding: 0.2rem 0.6rem;
filter: drop-shadow(1px 1px 3px rgb(0 0 0 / 0.1));
* {transition: none;
}
}
[data-tippy-root]::before {--size: 0.4rem;
content: '';
position: absolute;
left: calc(50% - var(--size));
top: calc(-2 * var(--size) + 1px);
border: var(--size) solid transparent;
border-bottom-color: var(--bg);
}
}
</style>