Pembolehubah 'Helper' dalam Svelte 5

DDD
Lepaskan: 2024-11-10 08:28:02
asal
922 orang telah melayarinya

Pembolehubah Helper dalam Svelte 5

Bye Bye Magical Svelte 4 $:

Berikutan catatan saya baru-baru ini Pengalaman dan Kaveat mengenai Svelte 5 Migration, saya ingin menyerlahkan beberapa teknik dan perubahan minda apabila beralih dari Svelte 4 ke Svelte 5.

Svelte 4 menggunakan "ajaib" $: dan biarkan dan lakukan semua pengangkatan berat untuk menjadikan kod reaktif. Kami juga menerima penugasan semula pembolehubah seperti

<script>
let arr = [1, 2, 3]
let value = 4

arr = [...arr, value]
</script>
Salin selepas log masuk

bukan kaedah mengemas kini/memutasi pembolehubah seperti push dll.

Saya agak terkejut mempelajari semula corak JS lama yang bagus menggunakan Svelte 5.

Tidak Perlu Reaktif Sepanjang Masa

Dan saya juga mungkin agak dimanjakan oleh let in Svelte 4 , tiada alasan tentang kereaktifan, ia disertakan jika perlu. Tetapi tidak semua pembolehubah perlu reaktif. Juga pembolehubah bukan reaktif boleh dikemas kini dalam reaktif atau bahkan "kod mutasi tradisional". Keperluan sebenar untuk pembolehubah reaktif ialah apabila kami menggunakannya dalam UI (apabila pembolehubah ini dipaparkan dalam html/halaman dan kami memerlukannya untuk dikemas kini kemudian).

Anda mungkin menghadapi ralat dalam Svelte 5 seperti Tidak boleh menetapkan kepada keadaan terbitan, Negeri yang dirujuk dalam skopnya sendiri tidak akan dikemas kini. Adakah anda bermaksud untuk merujuknya dalam penutupan? atau derived_references_selfnA nilai terbitan tidak boleh merujuk sendiri secara rekursif jika menggunakan gaya pengekodan Svelte 4.

Contoh Pembolehubah Pembantu

Lihat contoh gaya kod Svelte 4 ini:

<script>
    let value;
    let derivedArr = []

    $: if (value) {
        derivedArr = [...derivedArr, value]
    }

    function random () {
        value = Math.floor(1 + Math.random() * 10)
    }
</script>

<button on:click="{random}">Generate Random Value</button>
<p>value: {value}</p>
<p>derivedArr: {derivedArr}</p>
Salin selepas log masuk

DEMO

Kami mempunyai dua pembolehubah reaktif dan Svelte 4 menyelesaikan kemas kini secara automatik. Kami hanya perlu ingat bahawa cara yang betul adalah dengan menetapkan semula pembolehubah.

Dalam Svelte 5 kita harus berfikir sedikit bagaimana untuk mencapai hasil yang sama. Dua pembolehubah yang kami gunakan tidak mencukupi, kami memerlukan satu lagi, satu pembantu.

Cara pilihan ialah menggunakan rune $derived().

<script>
    let value = $state();
    let helperArr = [];

    let derivedArr = $derived.by(() => {
      if (value) {
                helperArr.push(value);
                return helperArr;
        }
    });

    function random () {
        value = Math.floor(1 + Math.random() * 10)
    }
</script>

<button onclick="{random}">Generate Random Value</button>
<p>value: {value}</p>
<p>derivedArr: {derivedArr}</p>
Salin selepas log masuk

DEMO

Jika anda tahu cara yang lebih mudah untuk melakukan ini, beritahu saya.

Terdapat juga cara rune $effect() untuk mencapai perkara yang sama. Ia mungkin kelihatan lebih mudah tetapi kita harus mengelakkan kesan jika boleh (terutamanya kesan Svetlet 5 tidak berjalan pada pelayan/SSR).

<script>
    let value = $state();
    let helperArr = []
    let effectArr = $derived(helperArr);

    $effect.pre(() => {
            if (value) {
              helperArr.push(value)
            }
        })

    function random () {
        value = Math.floor(1 + Math.random() * 10)
    }
</script>

<button onclick="{random}">Generate Random Value</button>
<p>value: {value}</p>
<p>effectArr: {effectArr}</p>
Salin selepas log masuk

DEMO

Contoh Kehidupan Sebenar

Ini adalah contoh bagaimana saya cuba memindahkan halaman Svelte 4 dengan agak lurus ke hadapan ke Svelte 5. Saya mengambil sedikit masa untuk memikirkan semula kod itu. Halaman ini berfungsi sebagai carian siaran dengan fungsi "Muat Lagi" (menambah hasil atau pagging jika pengguna tidak mempunyai JS):

Svelte 4

<skrip>
    import Ikon daripada '../components/Icon.svelte';
    import { enhance } daripada '$app/forms';
    import { tick } daripada 'svelte';

    borang surat kebenaran eksport;
    eksport biarkan searchingLang;
    eksport biarkan l;

    biarkan keputusan = [];
    biarkan carian sebelumnya = '';
    biarkan searchTerm;
    biarkan skip;

    $: if (!!form && form?.thereIsMore) {
        searchTerm = form.searchTerm;
        langkau = Nombor(bentuk?.langkau) 20;
    }

    $: if (!!form?.searchResultFromAction) {
        if (Search Sebelumnya == form.searchTerm && form.thereWasMore) {
            keputusan = [...hasil, ...form.searchResultFromAction];
        } lain {
            keputusan = [...form.searchResultFromAction];
            sebelumnyaSearch = form.searchTerm;
        }
    }

    fungsi async intoView(el) {
        tunggu tandakan();
        jika (el.attributes.index.nodeValue == langkau - 20 && langkau != tidak ditentukan) {
            el.scrollIntoView({ gelagat: 'licin' });
        }
    }
</skrip>

{#if results.length}
    <ol>
        {#setiap keputusan sebagai item, indeks}
            <li use:intoview aria-posinset="{index}">
                <!-- pengguna tanpa javascript telah mengira susunan keputusan dalam penomboran dan css melumpuhkan penomboran standard -->
                <!-- pengguna dengan javascript mempunyai penomboran ol ul standard dan memuatkan lebih banyak ciri -->
                <noscript>{Nombor(indeks) 1 Nombor(borang?.langkau)}. </noscript>
                <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a>
            </li>
        {/setiap}
    </ol>

    {#if form?.thereIsMore}
        <bentuk kaedah="POST" action="?/search&skip=%7Bskip%7D&thereWasMore=%7Bform?.thereIsMore%7D" gunakan:meningkatkan autolengkap="mati">
            <label>
                <!-- Mungkin kita tidak perlu mengikat nilai kerana ini adalah input tersembunyi -->
                <!-- <input name="searchTerm" type="hidden" bind:value={searchTerm} /> -->
                <input name="searchTerm" type="hidden" value="{searchTerm}">
            </label>
            <button aria-label="Butang untuk memuatkan lebih banyak hasil carian">



<p>Svelte 5<br>
</p>
<pre class="brush:php;toolbar:false"><skrip>
    import Ikon daripada '../components/Icon.svelte';
    import { enhance } daripada '$app/forms';
    import { tick } daripada 'svelte';

    biarkan { form, searchingLang, l } = $props();

    biarkan carian sebelumnya = '';
    biarkan langkau = $derived.by(() => {
        jika (!!borang && borang?.adaLagi) {
            kembalikan Nombor(borang?.langkau) 20;
        }
    });

    biarkan helperResultsArr = [];
    biarkan keputusan = $derived.by(() => {
        if (!!form?.searchResultFromAction) {
            if (Search Sebelumnya == form.searchTerm && form.thereWasMore) {
                helperResultsArr.push(...form.searchResultFromAction);
                return helperResultsArr;
            } lain {
                helperResultsArr = [];
                helperResultsArr.push(...form.searchResultFromAction);
                sebelumnyaSearch = form.searchTerm;
                return helperResultsArr;
            }
        } else kembalikan [];
    });

    fungsi async intoView(el) {
        tunggu tandakan();
        jika (el.attributes.index.nodeValue == langkau - 20 && langkau != tidak ditentukan) {
            el.scrollIntoView({ gelagat: 'licin' });
        }
    }
</skrip>

{#if results.length}
    <ol>
        {#setiap keputusan sebagai item, indeks}
            <li use:intoview aria-posinset="{index}">
                <!-- pengguna tanpa javascript telah mengira susunan keputusan dalam penomboran dan css melumpuhkan penomboran standard -->
                <!-- pengguna dengan javascript mempunyai penomboran ol ul standard dan memuatkan lebih banyak ciri -->
                <noscript>{Nombor(indeks) 1 Nombor(borang?.langkau)}. </noscript>
                <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a>
            </li>
        {/setiap}
    </ol>

    {#if form?.thereIsMore}
        <bentuk kaedah="POST" action="?/search&skip=%7Bskip%7D&thereWasMore=%7Bform?.thereIsMore%7D" gunakan:meningkatkan autolengkap="mati">
            <label>
                <input name="searchTerm" type="hidden" value="{form.searchTerm}">
            </label>
            <button aria-label="Butang untuk memuatkan lebih banyak hasil carian">



<p>Itu sahaja buat masa ini. </p>

<p>PS: Jangan teragak-agak untuk memberitahu saya jika anda akan melakukan penghijrahan dengan cara yang berbeza.</p>


          

            
        </button></bentuk>
Salin selepas log masuk

Atas ialah kandungan terperinci Pembolehubah 'Helper' dalam Svelte 5. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan