当前位置: 首页 > 知识库问答 >
问题:

svelte - Svelte tooltip 更新机制:函数 vs 直接传入内容的区别?

澹台奇略
2024-12-09
<script>
    import tippy from 'tippy.js';

    let content = $state('Hello!');

    function tooltip(node, content) {
        $effect(() => {
            console.log(content)
            const tooltip = tippy(node, {content});

             return tooltip.destroy;
        });
    }
</script>

<input bind:value={content} />

<button use:tooltip={content}>
    Hover me
</button>

本人 svelte 小白, 这是我在实现 svelte 官网上的一个案例时,直接传入 content 给 tooltip 函数的写法

这种写法在 content 更新时, tooltip 中的内容不会更新

官方的写法是将 content 包装成函数传入, 解释如下:

We’re passing in a function, rather than the options themselves, because the tooltip function does not re-run when the options change.

为什么直接传入 content 的时候,在 content 更新时不会更新 tooltip

同时为什么使用函数时会更新呢

共有2个答案

姚俊材
2024-12-09

直接将content传递给tooltip函数会让tooltip的内容在content更新时不会自动更新。这是因为这传递的是一个静态值,而不是一个动态的函数。当你直接将content作为参数传入tooltip函数时,Tippy.js创建的tooltip实例只会在第一次初始化时读取这个值。之后即使content的值发生变化,tooltip实例并不会重新读取这个值,因为它没有被告知去更新。
你可以将content包装成一个函数传入。当tooltip被触发时,它会调用这个函数,从而获取最新的内容:

function tooltip(node, getContent) {
    $effect(() => {
        const tooltip = tippy(node, { content: getContent });
        return tooltip.destroy;
    });
}
孙凌
2024-12-09
### 回答

在 Svelte 中,当你直接传入 `content` 给 `tooltip` 函数时,`content` 的值在组件初始化时就被捕获并传递给 `tippy` 实例。这意味着,即使后续 `content` 的值发生变化,`tippy` 实例中使用的仍然是初始化时的值。

这是因为 Svelte 的响应式系统不会自动追踪传递给非响应式函数(如这里的 `tooltip` 函数)的变量的变化。一旦这些变量被捕获并传递给函数,它们就与后续的更新解耦了。

当你将 `content` 包装成一个函数传入时,这个函数会在每次 `tooltip` 需要重新评估其依赖项时被调用。这意味着每次 `content` 的值变化时,`tippy` 实例都会接收到最新的 `content` 值。这是因为函数每次调用时都会返回当前的 `content` 值,从而允许 `tippy` 实例使用最新的内容。

简而言之:

- **直接传入 `content`**:`content` 的值在初始化时被捕获,后续变化不会反映到 `tippy` 实例中。
- **传入函数**:函数每次调用时都会返回最新的 `content` 值,因此 `tippy` 实例能够反映 `content` 的最新变化。
 类似资料:
  • repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注意,在大多数时候有eval(repr(object)) == object。 >>> i = [] >>> i.append('item') >>> `i` "['item']" >>> repr(i) "['item']" 基本上,repr函数和反引号用来获取对象的可打印的表示形式。你可以通过定义类的__repr

  • 在我的程序中,我将一个数组传递给一个名为setArray()的方法。但我还是从数组中得到了0值。。 输入尺寸: 4 逐一输入元素:1 2 3 4 输出: 0

  • 我试图在我的SQL中用一个内部连接来做一个UPDATE语句。我已经做了示例,并将表名和表列编辑到我的表中。但我的MYSQL仍然不断给我一个错误(#1064)。 错误 您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册,在第5行的“来自收藏夹INNER JOIN图像ONfavorites.image=images.idW”附近使用正确的语法 SQL 提前感谢您在这一点上帮助我。 谨致问

  • 如果函数接口有指针参数,既可以把指针所指向的数据传给函数使用(称为传入参数),也可以由函数填充指针所指的内存空间,传回给调用者使用(称为传出参数),例如strcpy的函数原型为 char *strcpy(char *dest, const char *src); 其中src参数是传入参数,dest参数是传出参数。有些函数的指针参数同时担当了这两种角色,如select函数。其函数原型为: int

  • 我尝试用php(symfony应用程序)配置docker。 当我第一次构建容器时,symfony骨架应用程序出现在容器中,但任何其他构建都不会改变容器中的任何内容。 DOCKEFILE

  • 在useEffect钩子中,我设置了间隔,这是运行函数“calculateCircle”。在那里我做了一些逻辑,包括设置状态(使用useState钩子)。钩子中的变量会被更新,我会在页面上呈现并看到它们,但这个函数会保持对旧值的控制台登录。 我将我的组件更改为基于类的组件(没有挂钩),现在一切正常。但是我想知道使用钩子的问题是什么。 //没有钩子,它就能工作;

  • 下面是我的代码。我正在用一张传单画一张用Svelte的曲线图。但我得到一个错误“地图未定义”。我该怎么解决这个? 此外,我想添加一个图像作为背景,坐标绘制在给定的图像上。

  • 我有一个问题,在Visual Studio代码中,即使启用了编辑器,我也看不到用于合并冲突的工具栏。codeLens。 知道它还能是什么吗?我试图重新启动VS Code,禁用/启用editor.code镜头。我甚至安装/卸载了Gitlen-Git增压。 提前谢谢你。 我的输入参考来自:接受VS代码中未出现的传入更改