Svelte 操作不适用于非 Svelte JavaScript 库

Svelte Actions Are Not Working With Non-Svelte JavaScript Libraries

我有一个博客卡片列表,我已使用 Splide 将其转换为轮播。每当我切换到另一个页面时,我都想删除现有的 Splide 对象。我想使用 Svelte 动作来实现这个但我做不到。

<script>
  const splideAction = async (node, props)=>{
    
        const module = await import("@splidejs/splide");
        const Splide = module.default;
        const splide_css = await import("@splidejs/splide/dist/css/splide.min.css");
        const carousel = new Splide(".splide",{
        perPage:3,
        type:"loop",
        rewind: true,
        permove: 1,
        autoplay: true,
        breakpoints: {
            750: {
                perPage: 1
            },
            800:{
                perPage: 2
            }
        }
    }).mount();
        return {
            updated(){
                carousel.update();
                console.log("Updated")
            },
            destroy(){
                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>

当我点击其他博文的卡片时,我生成了一个新的轮播,而旧的轮播还在,如何删除它销毁

几件事:

  1. 我会在您的组件中同步导入 Splide 模块,而不是动态导入,因此它会在组件渲染后立即准备就绪。
  2. 我不确定异步导入 CSS 是否会像那样工作——这可能取决于您的捆绑器设置。无论哪种方式,我都会将其导入操作之外,方法是将其与 CSS 的其余部分捆绑在一起或通过 CDN。在下面的示例中,我使用 <svelte:head>.
  3. 从 CDN 加载它
  4. 我没有看到 Splide's API, so I'm not sure what carousel.update() would do. I don't think you need to return an "update" method from your action anyway, since your action isn't taking any parameters. The update method 中的“更新”函数旨在对您的操作参数的变化做出反应。
  5. 您错误地存储了对轮播的引用——您存储的是对 mount 的 return 值的引用,而不是构造函数。因此,destroy 被错误的变量调用。尝试这样的事情:
const carousel = new Splide();
carousel.mount();

虽然您的问题缺少一些上下文,但以下组件似乎有效。我简化了模板,因为我无权访问文章数据。您可以在 Svelte REPL 中实时查看。我添加了一个按钮来删除组件,这样您就可以看到轮播被破坏了。

<script>
    import Splide from '@splidejs/splide';
    
    function carousel(node) {
        const splide = new Splide(node, {
                perPage: 3,
                type: "loop",
                rewind: true,
                permove: 1,
                autoplay: true,
                breakpoints: {
                    750: {
                        perPage: 1
                    },
                    800: {
                        perPage: 2
                    }
                }
        });
        splide.mount();
        
        return {
            destroy: () => {
                splide.destroy();
                console.log('destroyed');
            }
        }
    }
</script>

<svelte:head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@3.0.9/dist/css/splide.min.css">
</svelte:head>

<div class="splide" use:carousel>
  <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide">Slide 01</li>
            <li class="splide__slide">Slide 02</li>
            <li class="splide__slide">Slide 03</li>
        </ul>
  </div>
</div>

<style>
    li {
        height: 300px;
        background: lightblue;
    }
</style>