当 Svelte 重用父 dom 元素时如何确保仅本地转换

2024-02-03

在 Svelte 中,我有一个组件用于显示两个不同列表中的项目。当这些项目从一个列表移动到另一个列表时,它们使用过渡来动画进入或退出。

不过,我还有一种方法可以过滤屏幕上显示的内容。显示一组新的项目将使用相同的组件,但具有不同的数据。在这种情况下,我不希望发生过渡动画。我假设添加local修饰符可以解决这个问题,但 Svelte 似乎并没有将父元素删除到列表中,而是重用它并在现有列表 DOM 元素中添加新数据。

我尝试重现我在下面的示例代码中看到的内容。

想要的行为:

  1. 单击 TODO 会将 TODO 从一个列表切换到另一个列表。
  2. 单击“切换类别”将切换列出的 TODO,而不需要动画<li>添加或删除的 TODO 的 s。

实际行为:

  1. 正如预期的那样发生。
  2. 切换的待办事项通过动画进行。

我怎样才能改变我的例子以获得我想要的效果?

应用程序.svelte:

<script>
    import Todos from './Todos.svelte';

    let todos = [
        { id: 1, category: 'personal', name: 'Walk dog', done: false },
        { id: 2, category: 'personal', name: 'Take out trash', done: false },
        { id: 3, category: 'work', name: 'Make login page functional', done: false },
        { id: 4, category: 'work', name: 'Make login page elegant', done: false }
    ];

    let currentCategory = 'personal';
    const toggleCategory = () => {
        currentCategory = currentCategory == 'personal' ? 'work' : 'personal';
    }

    const toggleTodo = id => {
        todos = todos.map(todo => {
            if (todo.id === id) {
                return { ...todo, done: !todo.done }
            }
            return todo;
        });
    }

    $: categoryTodos = todos.filter(x => x.category == currentCategory);
</script>

<button on:click={toggleCategory}>Switch Categories</button>
<Todos todos={categoryTodos} {toggleTodo}>
</Todos>

Todos.svelte:

<script>
    import { slide } from 'svelte/transition';
    export let todos;
    export let toggleTodo;

    $: complete = todos.filter(t => t.done);
    $: incomplete = todos.filter(t => !t.done);
</script>

<h1>Incomplete</h1>
<ul>
    {#each incomplete as {id, name} (id)}
    <li transition:slide|local on:click={() => toggleTodo(id)}>{name}</li>
    {/each}
</ul>
<h1>Complete</h1>
<ul>
    {#each complete as {id, name} (id)}
    <li transition:slide|local on:click={() => toggleTodo(id)}>{name}</li>
    {/each}
</ul>

Update

自 v3.28.0 起,此关键功能现已成为 Svelte 的一部分(请参阅issue https://github.com/sveltejs/svelte/issues/1469#issuecomment-698955660).

语法如下:

{#key expression}...{/key}

之前的回答

在 React 中,您可以使用keyprop 使渲染器重新创建一个可以重用的元素(相同的标签等)。

// React
<Todos items={items} key={currentCategory} />

但 Svelte 不支持key, 可以?嗯,有点。 Svelte 确实具有等效功能,但仅限于{#each ...} blocks.

语法是这样的(docs https://svelte.dev/docs#each-- 文档中没有提到这个精确的语法,但我想它只是被遗忘了):

{#each expression as name (key)}...{/each}

就像在 React 中一样,当键的值发生变化时(否则会重用),组件将被重新创建。

还有苏...

<script>
  export let allItems
  export let currentCategory

  $: items = allItems.filter(x => x.category === currentCategory)
</script>

{#each [items] as todos (currentCategory)}
  <Todos {todos} />
{/each}

呼呼。正确的?

Using currentCategory作为密钥将创建一个新的<Todos />每次类别更改时组件,这可能是您在您的情况下想要的。

就像在 React 中一样,必须明智地选择键的值,以便在每次需要时重新创建,但不能更多(否则它会杀死您的情况下所需的项间转换)。

键的值不限于每个循环中当前评估的项。它可以来自 Svelte 范围内的任何地方,因此您可以发挥创意。它甚至可以是一个内联对象{}这会重新创建......嗯,基本上一直!

Edit

您可以将 hack 变成它自己的组件,以便消费者获得更清晰的语法:

<!-- Keyed.svelte -->

<script>
    export let key
    // we just need a 1-length array
    const items = [0]
</script>

{#each items as x (key)}
    <slot />
{/each}

像这样使用:

<script>
  import Keyed from './Keyed.svelte'
  
  export let items
  export let category
</script>

<Keyed key={category}>
  <Todos {items} />
</Keyed>

See example https://svelte.dev/repl/2373af8e5b5448c1821ceffe95bd3f26?version=3.15.0在 Svelte 的 REPL 中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当 Svelte 重用父 dom 元素时如何确保仅本地转换 的相关文章

随机推荐

  • cuda:扭曲发散开销与额外算术

    当然 扭曲发散 通过if and switch语句 在 GPU 上要不惜一切代价避免 但是扭曲发散的开销是多少 仅调度some执行某些行的线程 与额外无用的算术 考虑以下虚拟示例 版本1 device int get D int A int
  • Android 4.4 不允许我保存使用 adb 命令捕获的图片

    我的目标是使用前置和后置摄像头自动执行捕获和保存图片的过程 我使用的是运行 Android 版本 4 4 2 的 Nexus 5 但尚未对其进行 root 我使用以下命令分别打开前置和后置摄像头 gt adb shell am start
  • 即使没有析构函数,非静态类成员也会被销毁吗?

    在 Bjarne Stroustrup 的 C 编程语言 第 4 版 第 17 6 节 生成默认操作 中提到了这一点 如果程序员声明了复制操作 移动操作或 类的析构函数 无复制操作 移动操作或 为该类生成析构函数 因此 我很困惑为什么Sub
  • 导入错误:无法导入名称操作

    尝试运行 django 项目 安装了requirements txt 中的所有内容 但仍然出现错误 from django contrib admin import ModelAdmin actions ImportError cannot
  • 为什么 binding() 在 e2e 测试中找不到双向绑定?

    The binding 函数似乎在 e2e 测试中找不到双向绑定 假设有以下绑定
  • 如何在 doInBackground 中的 AsyncTask 中显示 toast

    在我正在使用的一项活动中AsyncTask In doInBackground 我正在调用各种方法 在其中一种方法中 我遇到了异常 因此在 catch 块中我想在 Toast 中显示错误 我知道我可以使用Log但我还是更喜欢吐司 那么 如何
  • 将 XML 数据插入 Oracle 数据库

    我的任务是从一个数据库 非oracle db 获取数据并将该数据插入到另一个数据库 oracle 中 我能够以 XML 形式从源数据库获取数据 现在我必须将此 XML 作为输入传递到 oracle 数据库 以便将 XML 内的所有数据插入到
  • aufs au_opts_parse:1155:docker[2010] 未知选项 dirperm1

    我安装了 Docker 现在 当我的 Ubuntu 14 04 Trusty 系统尝试启动时 我收到以下消息 aufs au opts parse 1155 docker 2010 unknown option dirperm1 这意味着什
  • 为什么 webpack 需要一个空扩展名

    我试图弄清楚为什么 webpack 需要这个空扩展名 Inside resolve extensions总是有这样的配置 extensions js jsx 为什么不能只是这样 extensions js jsx 在较新的 Webpack
  • 如何下载 TFS 搁置集

    我需要将 TFS 中的搁置集下载到本地文件夹 Visual studio 2010 有没有下载工具集的工具或插件 如果你只需要将文件从搁置集中获取到本地文件夹 这是一个正常的过程 称为Unshelve http msdn microsoft
  • 即使 IP 更改或浏览器数据已清除,我如何识别网站上的唯一用户?

    我正在开发一个视频流网站 我想计算每个视频的独特观看次数 我参考了互联网上的一些网站 甚至询问了其他一些程序员 他们说要么使用 cookie 要么使用会话 要么使用 IP 地址 但这些事情会随着时间的推移而改变 另外 如果可能的话 我们可以
  • 如何处理 AWS Athena 中的嵌入换行符

    我在 AWS Athena 中创建了一个表 如下所示 CREATE EXTERNAL TABLE IF NOT EXISTS default test line breaks col1 string col2 string ROW FORM
  • 是否可以训练斯坦福 NER 系统来识别更多命名实体类型?

    我现在正在使用一些 NLP 库 stanford 和 nltk 斯坦福大学我看到了演示部分 但只是想问是否可以使用它来识别更多实体类型 因此 目前斯坦福的 NER 系统 如演示所示 可以将实体识别为人 名称 组织或位置 但认可的组织仅限于大
  • 从给定节点开始有向图的 BFS 遍历

    我的基本理解广度优先搜索图的遍历是 BFS Start from any node Add it to queue Add it to visited array While queue is not empty Remove head f
  • 添加用于将 Word 注释中的标题提取到 Excel 中的代码

    我有一些代码用于将 Word 中的注释提取到 Excel 中 但是 它只提取一级标题 直接标题 我可以添加哪些代码来提取 Excel 中不同列中的不同标题级别 我可以按样式选择这些不同的标题级别吗 如果我使用 MyOwnHeading 样式
  • Maven:在 pom.xml 中配置并行构建

    Maven 具有执行并行构建的能力 https cwiki apache org confluence display MAVEN Parallel builds in Maven 3 https cwiki apache org conf
  • jQuery 支持“:invalid”选择器

    我收到以下控制台消息 16 04 01 292 Error Syntax error unrecognized expression unsupported pseudo invalid http localhost 8080 assets
  • JHipster:将根域重定向到 www

    我正在从事搜索引擎优化工作 我想https pomzen com https pomzen com被重定向到https www pomzen com https www pomzen com 是否可以在 JHipster 项目中完成 还是在
  • 防止表单提交后重新加载页面

    有没有办法检测并停止页面是否正在重新加载 我有一个页面 在成功提交其中存在的表单后正在重新加载 我想要一个事件侦听器来查看页面是否正在重新加载并应该阻止它重新加载 我不能return false 成功提交注册表 在你的html中
  • 当 Svelte 重用父 dom 元素时如何确保仅本地转换

    在 Svelte 中 我有一个组件用于显示两个不同列表中的项目 当这些项目从一个列表移动到另一个列表时 它们使用过渡来动画进入或退出 不过 我还有一种方法可以过滤屏幕上显示的内容 显示一组新的项目将使用相同的组件 但具有不同的数据 在这种情