搜尋

首頁  >  問答  >  主體

在 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 天前348

全部回覆(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
  • 取消回覆