搜索

首页  >  问答  >  正文

在 Svelte 中将对象作为 props 传递使得 HTML 中的对象字段不会改变?

我有这个 Svelte 代码:

玩家.svelte:

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

    let audio;
</script>

<audio src={...} bind:this={audio} />
<PlayerControls {audio} />

PlayerControls.svelte:

<script>
    import PlayIcon from '../icons/PlayIcon.svelte';
    import PauseIcon from '../icons/PauseIcon.svelte';

    export let audio;

    const onClick = () => {
        if (audio?.paused) audio.play();
        else audio.pause();
    };
</script>

{#if audio?.paused}
    <PlayIcon {onClick} />
{:else}
    <PauseIcon {onClick} />
{/if}

如果我按播放图标,图标不会改变,但音频开始,如果我再次单击,音频停止,图标不变。似乎audio.paused仅在脚本中“更改”,而不是在html中。这里有什么问题,以及我对 Svelte 有什么不理解的地方?

P粉550823577P粉550823577243 天前347

全部回复(1)我来回复

  • P粉546179835

    P粉5461798352024-03-28 21:25:26

    在您给定的情况下,最强大的解决方案是利用特定的 <audio> 元素 事件 提醒 svelte 重新检查 ref 的状态。这允许 svelte 管理您的侦听器生命周期,并且还允许元素本身处理播放状态何时/如何更改的所有边缘情况。

    sssccc
    
    

    REPL

    原始答案

    我的评论中的文档链接涵盖了解决您问题的简单方法 反应性/更新数组和对象,就是简单地重新分配 audio 作为 onClick 处理程序中的最后一步。

    请记住,如果音频自行结束,这不会跟踪 paused 中的更改。

    const onClick = () => {
        if (audio?.paused) audio.play();
        else audio.pause();
        
        audio = audio;
    };

    REPL

    编辑

    我最初建议可以直接改变 paused 属性:

    const onClick = () => {
      if (audio?.paused) {
        audio.play();
        audio.paused = false;
      } else {
        audio.pause();
        audio.paused = true;
      }
    };

    但忽略了 audiorefpaused 是只读属性这一事实。

    回复
    0
  • 取消回复