Maison > interface Web > js tutoriel > Varaibles 'Aide' dans Svelte 5

Varaibles 'Aide' dans Svelte 5

DDD
Libérer: 2024-11-10 08:28:02
original
950 Les gens l'ont consulté

Varaibles Aide dans Svelte 5

Bye Bye Magical Svelte 4 $ :

Suite à mon récent article Expériences et mises en garde concernant la migration de Svelte 5, j'aimerais souligner certaines techniques et changements d'état d'esprit lors du passage de Svelte 4 à Svelte 5.

Svelte 4 utilise "magique" $: et laisse et fait tout le gros du travail pour rendre le code réactif. Nous avons également adopté la réaffectation des variables comme

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

arr = [...arr, value]
</script>
Copier après la connexion

au lieu de méthodes mettant à jour/muter des variables comme push, etc.

J'ai été assez surpris de réapprendre les bons vieux modèles JS en utilisant Svelte 5.

Pas besoin d'être réactif tout le temps

Et j'ai aussi probablement été assez gâté par l'intégration de Svelte 4, aucun raisonnement sur la réactivité, il était inclus si besoin. Mais toutes les variables ne doivent pas nécessairement être réactives. De plus, les variables non réactives peuvent être mises à jour en réactif ou même en "code de mutation traditionnel". Le véritable besoin d'une variable réactive est lorsque nous l'utilisons dans l'interface utilisateur (lorsque cette variable est rendue en html/page et que nous en avons besoin pour la mettre à jour plus tard).

Vous pouvez rencontrer des erreurs dans Svelte 5 comme Impossible d'attribuer à l'état dérivé, l'État référencé dans sa propre portée ne sera jamais mis à jour. Vouliez-vous le référencer à l'intérieur d'une fermeture ? ou dérivé_references_selfnUne valeur dérivée ne peut pas se référencer de manière récursive si vous utilisez le style de codage Svelte 4.

Exemple de variables d'assistance

Jetez un œil à cet exemple de style de code Svelte 4 :

<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>
Copier après la connexion

DÉMO

Nous avons deux variables réactives et Svelte 4 résout automatiquement les mises à jour. Nous devions seulement nous rappeler que la bonne façon consiste à réaffecter la variable.

Dans Svelte 5, nous devrions réfléchir un peu à la manière d'obtenir le même résultat. Les deux variables que nous utilisons ne suffisent pas, nous en avons besoin d'une de plus, celle d'assistance.

La méthode préférée consiste à utiliser une 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>
Copier après la connexion

DÉMO

Si vous connaissez un moyen plus simple de procéder, faites-le-moi savoir.

Il existe également une manière runique $effect() d'obtenir la même chose. Cela peut paraître encore plus simple mais nous devrions éviter les effets si possible (principalement les effets Svetlet 5 ne fonctionnent pas sur le serveur/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>
Copier après la connexion

DÉMO

Exemple réel

Voici l'exemple de la façon dont j'ai essayé de migrer assez directement la page Svelte 4 vers Svelte 5. Il m'a fallu un certain temps pour repenser le code. Cette page fonctionne comme une recherche de publications avec une fonctionnalité "Load More" (ajout de résultats ou pagination si un utilisateur n'a pas JS) :

Svelte 4

<script>
    importer l'icône depuis '../components/Icon.svelte' ;
    importer { améliorer } depuis '$app/forms' ;
    importer { tick } depuis 'svelte' ;

    exporter le formulaire de location ;
    export let searchLang ;
    exporter let l;

    laissez les résultats = [];
    laissez previousSearch = '';
    laissez searchTerm;
    laissez sauter;

    $ : if (!!form && form?.thereIsMore) {
        searchTerm = form.searchTerm;
        sauter = Nombre(formulaire?.skip) 20 ;
    }

    $ : si (!!form?.searchResultFromAction) {
        if (previousSearch == form.searchTerm && form.thereWasMore) {
            résultats = [...results, ...form.searchResultFromAction];
        } autre {
            résultats = [...form.searchResultFromAction];
            previousSearch = form.searchTerm;
        }
    }

    fonction asynchrone intoView(el) {
        attendre tick();
        if (el.attributes.index.nodeValue == skip - 20 && skip != non défini) {
            el.scrollIntoView({ behavior: 'smooth' });
        }
    }
</script>

{#if résultats.longueur}
    <ol>
        {#chaque résultat sous forme d'élément, d'index}
            <li use:intoview aria-posinset="{index}">
                <!-- les utilisateurs sans javascript ont calculé l'ordre des résultats dans la pagination et CSS désactive la numérotation standard ol ul -->
                <!-- les utilisateurs avec javascript ont une numérotation ol ul standard et chargent plus de fonctionnalités -->
                <noscript>{Numéro(index) 1 Nombre(formulaire?.skip)}. </noscript>
                <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a>
            &Lt;/li>
        {/chaque}
    </li>
</ol>

    {#if form?.thereIsMore}
        <formulaire m action="?/search&skip=%7Bskip%7D&thereWasMore=%7Bform?.thereIsMore%7D" utilisation:am saisie semi-auto="désactivé">
            
                <!-- Nous n'avons probablement pas besoin de lier la valeur car il s'agit d'une entrée cachée -->
                <!-- <input name="searchTerm" type="hidden" bind:value={searchTerm} /> --->
                <input name="searchTerm" type="hidden" value="{searchTerm}">
            étiquette>
            <button aria-label="Bouton pour charger plus de résultats de recherche">



<p>Svelte 5<br>
</p>
<pre class="brush:php;toolbar:false"><script>
    importer l'icône depuis '../components/Icon.svelte' ;
    importer { améliorer } depuis '$app/forms' ;
    importer { tick } depuis 'svelte' ;

    let { form, searchLang, l } = $props();

    laissez previousSearch = '';
    laissez sauter = $derived.by(() => {
        if (!!form && form?.thereIsMore) {
            return Number(form?.skip) 20 ;
        }
    });

    laissez helperResultsArr = [];
    soit les résultats = $derived.by(() => {
        si (!!form?.searchResultFromAction) {
            if (previousSearch == form.searchTerm && form.thereWasMore) {
                helperResultsArr.push(...form.searchResultFromAction);
                retourner helperResultsArr ;
            } autre {
                helperResultsArr = [];
                helperResultsArr.push(...form.searchResultFromAction);
                previousSearch = form.searchTerm;
                retourner helperResultsArr ;
            }
        } sinon return [];
    });

    fonction asynchrone intoView(el) {
        attendre tick();
        if (el.attributes.index.nodeValue == skip - 20 && skip != non défini) {
            el.scrollIntoView({ behavior: 'smooth' });
        }
    }
</script>

{#if résultats.longueur}
    <ol>
        {#chaque résultat sous forme d'élément, d'index}
            <li use:intoview aria-posinset="{index}">
                <!-- les utilisateurs sans javascript ont calculé l'ordre des résultats dans la pagination et CSS désactive la numérotation standard ol ul -->
                <!-- les utilisateurs avec javascript ont une numérotation ol ul standard et chargent plus de fonctionnalités -->
                <noscript>{Numéro(index) 1 Nombre(formulaire?.skip)}. </noscript>
                <a href="/act/%7BsearchingLang%7D/%7Bitem.id%7D/present/text">{item.title}</a>
            &Lt;/li>
        {/chaque}
    </li>
</ol>

    {#if form?.thereIsMore}
        <formulaire m action="?/search&skip=%7Bskip%7D&thereWasMore=%7Bform?.thereIsMore%7D" utilisation:am saisie semi-auto="désactivé">
            
                <input name="searchTerm" type="hidden" value="{form.searchTerm}">
            étiquette>
            <button aria-label="Bouton pour charger plus de résultats de recherche">



<p>C'est tout pour le moment. </p>

<p>PS : N'hésitez pas à me faire savoir si vous feriez la migration d'une manière différente.</p>


          

            
        </button></formulaire>
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal