Svelte Actions对接非Svelte JS库Splide失效 无法销毁旧轮播实例
Svelte Splide 实例残留无法销毁问题解决方案
问题根因
- Action返回值类型错误:你定义的
splideAction是async函数,默认返回Promise对象,Svelte无法从Promise中识别destroy回调,导致页面卸载时销毁逻辑从未执行。 - 选择器使用错误:初始化Splide时使用全局类选择器
.splide,当页面存在多个轮播容器时会匹配到错误实例,也会导致销毁逻辑作用对象错误。
修正后的实现代码
<script> const splideAction = (node, props) => { // 存储Splide实例引用 let carousel = null; // 异步加载资源不影响外层函数返回 const initSplide = async () => { const module = await import("@splidejs/splide"); const Splide = module.default; await import("@splidejs/splide/dist/css/splide.min.css"); // 直接传入当前绑定的DOM节点,不要用全局选择器 carousel = new Splide(node, { perPage:3, type:"loop", rewind: true, perMove: 1, // 修正原代码拼写错误,原permove不生效 autoplay: true, breakpoints: { 750: { perPage: 1 }, 800:{ perPage: 2 } } }).mount(); }; initSplide(); return { updated() { if (carousel) carousel.update(); console.log("Updated") }, destroy() { // 销毁前判断实例是否存在,避免报错 if (carousel) { carousel.destroy(); console.log("destroy") } } } } </script> <div class="splide" use:splideAction> <div class="splide__track" > <div class="splide__list" > {#each [...metadata.related_articles] as article (article.id)} <div class="splide__slide flex"> <Card title="{article.title}" date="{article.date}" slug="{article.slug}" category="{article.category}" image="{article.image}" /> </div> {/each} </div> </div> </div>
修改说明
- 移除了action外层的async声明,保证外层函数直接返回带
destroy、updated回调的对象,Svelte可以正确注册销毁逻辑,页面切换时会自动触发destroy方法。 - 初始化Splide时直接传入action接收的
node参数,保证操作的是当前绑定的轮播容器,不会匹配到其他页面残留的容器。 - 增加了实例存在判断,避免异步加载未完成时调用方法报错,同时修正了原配置项
permove的拼写错误为驼峰格式perMove。
内容的提问来源于stack exchange,提问作者Lucretius
相关产品推荐
相关产品推荐

