Svelte基础
Advanced Svelte
Advanced reactivity
Motion
Advanced bindings
Advanced transitions
Context API
Special elements
<script module>
Next steps
Basic SvelteKit
Introduction
Routing
Loading data
Headers and cookies
Shared modules
API routes
$app/state
Errors and redirects
Advanced SvelteKit
Page options
Link options
Advanced routing
Advanced loading
Environment variables
Conclusion
嗨,小主!这次我们练习怎么在使用动作(use actions)时传递参数。首先动作的第一个参数是它绑定的Dom元素。
还是举个例子🌰: 我们先前提到动作很适合用来添加提示(tooltip),现在我们就使用Tippy.js
库给按钮<button>
添加上tooltip。
当你把鼠标移动到按钮上时,你就会看到它了。
但是tooltip上什么信息也没有。
因为tooltip显示的信息通常都很个性——不同的Dom元素显示的内容不一样。你也不想为每个需要显示的Dom元素都写一个tooltip动作吧?!我们可以在使用动作时把显示内容当作参数:
首先让动作接收一个函数类型的参数,这个函数会返回创建提示信息Tippy
需要的配置信息.注意第一个参数node
是当前Dom元素也就是<button>
—— 这个参数有贴心的Svelte自动传入.
Like transitions and animations, an action can take an argument, which the action function will be called with alongside the element it belongs to. In this exercise, we want to add a tooltip to the
<button>
using theTippy.js
library. The action is already wired up withuse:tooltip
, but if you hover over the button (or focus it with the keyboard) the tooltip contains no content. First, the action needs to accept a function that returns some options to pass to Tippy:
function tooltip(node, fn) {
$effect(() => {
const tooltip = tippy(node, fn());
return tooltip.destroy;
});
}
这里我们使用了函数类型的参数而不是直接使用包含配置信息的对象,这样当需要显示的内容变化时
tooltip
也会跟着更新,而不是一直显示原来的内容。都是智慧!💕
We’re passing in a function, rather than the options themselves, because the
tooltip
function does not re-run when the options change.
然后在使用动作时传递参数给它:
Then, we need to pass the options into the action:
<button use:tooltip={() => ({ content })}>
Hover me
</button>
在上个版本Svelte 4的时候,动作需要返回一个包含
update
和destroy
的对象,现在仍然适用,但我们现在更推荐使用$effect
In Svelte 4, actions returned an object with
update
anddestroy
methods. This still works but we recommend using$effect
instead, as it provides more flexibility and granularity.
<script>
import tippy from 'tippy.js';
let content = $state('Hello!');
function tooltip(node) {
$effect(() => {
const tooltip = tippy(node);
return tooltip.destroy;
});
}
</script>
<input bind:value={content} />
<button use: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>