记住 <slot /> Svelte 中的内容

问题描述 投票:0回答:1

在我的 SvelteKit 项目中,我有一个布局,应该水平显示所有彼此相邻的页面,但它们都是

100vw
宽,因此一次只有一个显示在屏幕“内”(其他页面位于屏幕的左/右),并且当从一个页面导航到另一页面时,它们都应该很好地向侧面滑动,以便您导航到的页面显示在屏幕的中心。 这里是 Svelte 项目中的一个快速演示,展示了我希望它如何工作。

但是,我想在SvelteKit项目中实现这一点,我无法提前加载所有页面的内容。相反,当前页面内容是使用

<slot />
文件中的
+layout.svelte
加载的,而我对其他页面的解决方法是显示一些虚拟文本。 这里是另一个 Svelte 项目中的快速演示,反映了这一点。

这已经足够好了,但是如果当前页面在离开当前页面时保留其内容,而不是立即将其内容更改为虚拟文本,那就太好了。

我的问题是:我能以某种方式将

<slot />
加载的旧内容保留几秒钟然后消失吗?

这是我的

+layout.svelte
文件中的 SvelteKit 代码当前的样子:

<div class="pages" style:--shownPageIndex={shownPageIndex}>

    {#each mainPages as mainPage, pageIndex (mainPage.name)}

        <div class="page" style:--pageIndex={pageIndex}>

            {#if isUrlLeadingToMainPage($page.url.pathname, mainPage)}
                <h1>{mainPage.name}</h1>
                
                <!--
                     The problem is here. When going to another page, the condition
                     in this #if becomes false, so the <slot /> below is immediately
                     removed, and the :else-part is shown instead. I want to delay this
                     for 1 second. But for the page I'm coming to, the change should
                     happen immediately. 
                -->
                <slot />
                
            {:else}

                <div class="fakedPageContent">
                    <h1>{mainPage.name}</h1>
                    <p>This is the faked content...</p>
                </div>

            {/if}

        </div>

    {/each}

</div>
svelte sveltekit
1个回答
0
投票

您可以尝试复制导航上的页面内容,例如使用路由

/paging/[page]
将页面索引存储在参数中:

import { onNavigate } from '$app/navigation';
import { page } from '$app/stores';

let pageContents = [];
let viewport;

onNavigate(e => {
    const route = '/paging/[page]';
    if (e.from.route.id != route || e.to.route.id != route)
        return;

    const from = +e.from.params.page;
    const page = viewport.querySelector(`[data-index="${from}"]`);
    pageContents[from] = [...page.cloneNode(true).childNodes];
});

function insert(node, children) {
    node.append(...children.map(child => child.cloneNode(true)));
}
<div class="viewport" bind:this={viewport}>
    {#each pages as page, i}
        <div class="page" data-index={i}>
            {#if i == $page.params.page}
                <slot />
            {:else}
                {#if i in pageContents}
                    <div use:insert={pageContents[i]}></div>
                {:else}
                    <div>...</div> <!-- not loaded before -->
                {/if}
            {/if}
        </div>
    {/each}
</div>
© www.soinside.com 2019 - 2024. All rights reserved.