【问题标题】:update component when progress value changes进度值更改时更新组件
【发布时间】:2020-09-07 20:35:42
【问题描述】:

我有一个显示百分比的进度条,我遇到的问题是它没有正确更新,我试图让它在半秒后从 0 加载,然后随着它的增加显示 $progress 值,但是目前它最初会跃升至 50% 左右,但随后会停留在那里并且不会进一步更新。

我怎样才能让它显示更新的进度?

<script>  

import { progress } from '../../store';

let width = 0

setTimeout(() => width = $progress, 500)

$: animatedWidth = width

</script>

<div class="container">
  <div class="line">
        <div class="animation" style="width: {animatedWidth}%"></div>
    </div>
</div>

【问题讨论】:

  • 您可以更新商店文件以查看您的进度变量吗?而且我没有看到任何值的更新。
  • $progress 变量在一分钟左右从 0 变为 100,这工作正常,它正在获取这个值,只是组件没有自动刷新,如果页面重新加载它会跳转到正确的位置
  • 好吧,setTimeout 只会更新一次width,并且该更新将在代码加载和执行后 500 毫秒发生,但可能在组件甚至安装之前发生,导致没有 视觉更新。您应该使用持续时间较短的setInterval(重复、更频繁的更新),并将其移至 Svelte 的 onMount 生命周期方法中,以便仅在组件实际安装并可见后才开始更新。使用 Svelte 的 destroy 生命周期函数进行清理 (clearInterval)。
  • 或者,如果您的商店已经在模拟一段时间内的进度,则根本不要使用setTimeout,而是直接将宽度映射到商店值style="width: {$progress}%"。
  • 它直接模拟随着时间的推移但是我需要在动画开始之前添加延迟,我该怎么做?

标签: svelte svelte-3


【解决方案1】:

如果您想在没有 CSS 的情况下对其进行动画处理,也可以使用补间商店,这非常简单,这是一个 REPL:https://svelte.dev/repl/6ef1130a13f641f2bf72c67a16ea429f?version=3.22.3

<script>
import { readable } from 'svelte/store';
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';

const time = readable(new Date(), function start(set) {
    const interval = setInterval(() => {
        set(new Date());
    }, 1000);

    return function stop() {
        clearInterval(interval);
    };
});

const width = tweened(0, {
    duration: 300,
    easing: cubicOut,
    delay: 3000
});

let started = false;

$: if(started) {
    width.set($time.getSeconds());
}
</script>

<p>
    {$width}
</p>
{#if !started}
    <button on:click={() => started = true}>
        Start
    </button>
{/if}

我创建了 time 商店作为您商店的替代品(因为您没有提供它的代码)。 width 存储是重要的部分,它将第一次更新延迟 3 秒,然后继续更新。显然,一旦达到极限,它将变为 0,因为一分钟只有 60 秒。 ;) 你只需要订阅time 商店:width.set($time.getSeconds());

所以基本上你所要做的就是导入补间存储并使用:

const width = tweened(0, {
    duration: 300,
    delay: 500
});

width.set($progress);

然后将元素宽度设置为{$width}。

【讨论】:

    【解决方案2】:

    您可以使用setTimeout 和setInterval 的组合。我使用以下代码为您创建了REPL:

    <script>
      import { onMount } from "svelte";
    
      let width = 0;
      let interval;
    
      onMount(() => {
        setTimeout(() => {
          width = 1;
          interval = setInterval(() => {
            if (width <= 100) {
              width += 1;
            } else {
              clearInterval(interval);
            }
          }, 1000);
        }, 500);
      });
    
      $: animatedWidth = width;
    </script>
    

    你基本上做的是在延迟 500 毫秒后使用 setTimeout 启动动画。之后,它将更新宽度,直到达到 100,然后它将结束间隔。为了使示例更容易,我使用 1 作为起始值,但您可以使用导入的商店值轻松完成此操作。

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2017-08-14
      • 2019-05-12
      • 1970-01-01
      • 2021-10-03
      • 2019-07-28
      • 2017-11-30
      • 1970-01-01
      相关资源
      最近更新 更多