簡體   English   中英

防止在 onMount 之后的第一次渲染時出現 Svelte 過渡

[英]Prevent Svelte transition on first render after onMount

我在 Svelte 3.55.0 中使用以下代碼。

首先,我有一個空網頁,因為我沒有要呈現的items 然后, onMount觸發,我從 API fetch一些items 。最后,項目被渲染。

<script>
import { slide } from "svelte/transition";
import { onMount } from "svelte";

// Initially we have no items.
let items = [];
let id = 0;

onMount(() => {
    // Fetch items from API.
    items = [
        {id: id, name: `item ${id++}`},
        {id: id, name: `item ${id++}`},
        {id: id, name: `item ${id++}`},
    ];
});

function addItem() {
    items = [
        ...items,
        {id: id, name: `item ${id++}`},
    ];
}
</script>

<div>
    <button on:click={addItem}>add</button>
    {#each items as it (it.id)}
        <div transition:slide>
            <p>{it.id} {it.name}</p>
        </div>
    {/each}
</div>

問題是fetch得到了 50 個項目,我不想為它們中的任何一個播放過渡。 但是,我確實希望僅在列表內部添加或刪除單個項目時進行轉換。

有沒有辦法達到這種效果?

沙盒: https://codesandbox.io/s/blue-shape-njxx9o?file=/App.svelte

這可以通過在主元素周圍添加一個#if塊來實現,這樣它只在獲取項目后呈現,並將|local標志添加到轉換 -教程

REPL

(就像這里的過渡似乎只有在外部元素具有display:flex時才能正確播放)

<script>
    import { slide } from "svelte/transition";
    import {onMount} from 'svelte'

    let items = [];
    let id = 0;
    let itemsFetched = false

    onMount(async() => {
        setTimeout(() => {
            items = [
                {id: id, name: `item ${id++}`},
                {id: id, name: `item ${id++}`},
                {id: id, name: `item ${id++}`},             
            ];
            console.log('fetched')
            itemsFetched = true
        },1000)
    })

    function addItem() {
        items = [
            ...items,
            {id: id, name: `item ${id++}`},
        ];
    }
</script>

<button on:click={addItem}>add</button>

{#if itemsFetched}
<div id="outer">
    {#each items as it (it.id)}
    <div transition:slide|local={{duration: 2000}}>
        <p>{it.id} {it.name}</p>
    </div>
    {/each}
</div>
{/if}

<style>
    #outer {
        display: flex;
        flex-direction: column;
    }
</style>

替代#await REPL

<script>
    import { slide } from "svelte/transition";
    import {onMount} from 'svelte'

    let items = [];
    let id = 0;

    function fetchItems() {
        return new Promise(res => {
            setTimeout(() => {
                items = [
                    {id: id, name: `item ${id++}`},
                    {id: id, name: `item ${id++}`},
                    {id: id, name: `item ${id++}`},             
                ];
                console.log('fetched')
                res()
            },1000)
        })      
    }

    function addItem() {
        items = [
            ...items,
            {id: id, name: `item ${id++}`},
        ];
    }
</script>

<button on:click={addItem}>add</button>

{#await fetchItems() then _}
<div id="outer">
    {#each items as it (it.id)}
    <div transition:slide|local={{duration: 2000}}>
        <p>{it.id} {it.name}</p>
    </div>
    {/each}
</div>
{/await}

<style>
    #outer {
        display: flex;
        flex-direction: column;
    }
</style>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM