Svelte - 更新值时防止重新渲染

时间:2021-06-17 21:12:59

标签: svelte svelte-3

我正在制作一个基于 CSS 的自定义动画,如下所示,但我不想在初始渲染时设置动画。起初,我认为我可以轻松实现这一点,创建一个在安装时设置的新标志。但是,我不确定如何实现这一点,因为我在顶层创建的所有变量都会在更新时导致重新渲染。

我读到在顶层声明的任何内容都会导致重新渲染分配。因此,我被迫在函数内创建此标志,但这样做并不能让我访问 HTML 中的变量。我怎样才能做到这一点?

    <script lang="ts">
      import { onMount } from 'svelte';
      import classnames from 'classnames';

      let element: HTMLDivElement;
      let mounted = false;

      onMount(() => {
        const animationEndHandler = () => {
          element.classList.remove(animation);
        };
        element.addEventListener('animationend', animationEndHandler);

        mounted = true; // This needs to not cause re-rendering.

        return () => {
          element.removeEventListener('animationend', animationEndHandler);
        };
      });

      export let animate: boolean;
      export let animation: string;
    </script>

    <div
      class={classnames('animated', { [animation]: animate && mounted })} // <== This attaches the variable `animation` when `animate && mounted` is true.
      bind:this={element}
    >
      <slot />
    </div>

2 个答案:

答案 0 :(得分:0)

我通过创建一个整数计数器并验证它大于 0 来解决它。这很丑陋,但我找不到任何其他方法。

答案 1 :(得分:0)

如果您在 onMount 中添加“类”,而不是在元素上使用 class 指令,应该可以正常工作吗? (唯一的一点是,我们还需要将 css 动画类名称添加到 :global() 范围,因为 svelte 可能会删除未使用的 css 类)。

<script>
    onMount(() => {
        const animationEndHandler = () => {
            element.classList.remove(animation);
        };
        element.addEventListener('animationend', animationEndHandler);

        element.classList.add(animation);

        return () => {
            element.removeEventListener('animationend', animationEndHandler);
        };
    });
</script>