Svelte中如何禁用父组件挂载与卸载阶段的过渡动画
问题成因
这不是Svelte框架本身的bug,是过渡系统的默认行为导致的:
- Svelte默认的过渡触发规则是:元素只要挂载进DOM,就会执行绑定的进入过渡;只要从DOM移除,就会执行绑定的退出过渡,和元素被移除、挂载的原因无关。
- 页面加载时偶发的展开动画,是
nav元素首次随组件初始化挂载时,自动触发的进入slide效果。 - 路由跳转瞬间的折叠动画,是当前页组件随路由切换被整体销毁,
nav元素从DOM移除时自动触发的退出slide效果,和当前isExpanded的实际取值没有关系。
可落地的解决方法
方案1:用Svelte原生能力配置,改动最小
关闭首次挂载的自动进入动画,避免页面加载时莫名播放展开效果
在组件最顶部加入配置:<svelte:options intro={false} />该配置的作用是:所有元素第一次随组件初始化挂载时,不执行进入过渡;只有后续状态变化(比如手动点击按钮切换
isExpanded,让被{#if}移除的nav重新挂载)时,才会触发对应的进入动画。屏蔽路由跳转时的被动卸载动画
给slide过渡加上|local修饰符,修改原来的nav绑定:{#if isExpanded} <nav transition:slide|local> Content </nav> {/if}|local修饰符的作用是:只有元素因为自身所在的{#if}条件变化被挂载/卸载时,才触发对应过渡;如果元素是因为整个父组件被路由跳转销毁而被移除,不会触发任何过渡,自然不会出现跳转瞬间的突兀折叠效果。
方案2:放弃条件块卸载,用CSS控制显隐(适配复杂度更高的场景)
如果你的菜单有更复杂的状态逻辑,可以不依赖{#if}卸载元素,改用CSS类控制显隐,从根源上避免元素被动卸载触发的动画:
<script> import { slide } from 'svelte/transition'; let isExpanded = true; </script> <button on:click={()=>isExpanded=!isExpanded}>Expand/Collapse</button> <nav class:hidden={!isExpanded} transition:slide > Content </nav> <a href="/some-page">There is no menu in this page</a> <style> .hidden { display: none; } </style>
这个写法下,nav元素始终存在于DOM中,不会因为组件被路由销毁时触发突兀的退出动画,同时可以提前给元素设置默认展开的初始样式,避免加载时的初始动画问题。
内容的提问来源于stack exchange,提问作者rohanharikr
相关产品推荐
相关产品推荐

