我有这个 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粉5461798352024-03-28 21:25:26
在您给定的情况下,最强大的解决方案是利用特定的 <audio>
元素 事件 提醒 svelte 重新检查 ref 的状态。这允许 svelte 管理您的侦听器生命周期,并且还允许元素本身处理播放状态何时/如何更改的所有边缘情况。
sssccc
我的评论中的文档链接涵盖了解决您问题的简单方法 反应性/更新数组和对象,就是简单地重新分配 audio
作为 onClick
处理程序中的最后一步。
请记住,如果音频自行结束,这不会跟踪 paused
中的更改。
const onClick = () => { if (audio?.paused) audio.play(); else audio.pause(); audio = audio; };
我最初建议可以直接改变 paused
属性:
const onClick = () => { if (audio?.paused) { audio.play(); audio.paused = false; } else { audio.pause(); audio.paused = true; } };
但忽略了 audio
是 ref
且 paused
是只读属性这一事实。