在 Svelte 中将对象作为 props 传递使得 HTML 中的对象字段不会改变?
P粉550823577
P粉550823577 2024-03-27 23:43:30
0
1
351

我有这个 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粉550823577
P粉550823577

全部回复(1)
P粉546179835

在您给定的情况下,最强大的解决方案是利用特定的 <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 是只读属性这一事实。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板