Comment rendre la localstorage réactive à Vue
Le système réactif de Vue.js est l'une de ses forces fondamentales, mais cela peut être mystérieux pour quiconque ne comprend pas ses mécanismes sous-jacents. Par exemple, pourquoi cela fonctionne-t-il avec des objets et des tableaux mais pas avec d'autres choses comme localStorage? Cet article répondra à cette question et montrera comment faire fonctionner le système réactif de Vue avec LocalStorage.
Si vous exécutez le code suivant, vous constaterez que le compteur est affiché comme une valeur statique et ne changera pas comme prévu en raison des modifications d'intervalle dans LocalStorage:
Nouveau Vue ({ el: "#counter", Données: () => ({ compteur: localstorage.getItem ("compteur") }), calculé: { Même() { Renvoie ce.Counter% 2 == 0; } }, modèle: `<div> <div>Compteur: {{compteur}}</div> <div>Le compteur est {{même? 'même': 'Odd'}}</div> </div>' });
// quelque part-file.js setInterval (() => { const compter = localStorage.getItem ("compteur"); localStorage.SetItem ("Counter", compteur 1); }, 1000);
Bien que counter
dans l'instance Vue soit réactive, elle ne change pas uniquement parce que nous avons changé sa source dans LocalStorage.
Il existe de nombreuses façons de résoudre ce problème, et la meilleure façon est probablement d'utiliser Vuex et de maintenir les valeurs stockées synchronisées avec LocalStorage. Mais que se passe-t-il si nous avons juste besoin d'une solution aussi simple que dans cet exemple? Nous devons avoir une compréhension approfondie du fonctionnement des systèmes réactifs de Vue.
Réactivité à Vue
Lorsque Vue initialise une instance de composant, il observe data
. Cela signifie que cela iratera sur toutes les propriétés des data
et les convertira en getter / setter en utilisant Object.defineProperty
. En définissant un secteur personnalisé pour chaque propriété, Vue peut savoir quand la propriété change et peut informer les dépendances qui doivent réagir au changement. Comment sait-il quelles dépendances dépendent d'une certaine propriété? En tirant parti des Getters, il peut être enregistré lorsque les propriétés calculées, les fonctions d'observateur ou les fonctions de rendu accèdent aux propriétés des données.
// core / instance / state.js fonction initdata () { // ... observer (données) }
// Core / Observer / index.js Fonction d'exportation observer (valeur) { // ... Nouveau observateur (valeur) // ... } EXPORT CLASSE Observer { // ... constructeur (valeur) { // ... this.walk (valeur) } marche (obj) { const Keys = object.keys (obj) pour (soit i = 0; i <keys.length i d keys><p> Alors, pourquoi localstorage n'est-il pas réactif? <strong>Car ce n'est pas un objet avec des attributs.</strong></p> <p> Mais attendez. Nous ne pouvons pas définir les getters et les setters avec des tableaux, mais en Vue, les tableaux sont toujours réactifs. En effet, les tableaux sont un cas spécial en Vue. Pour avoir des baies réactives, Vue a réécrit les méthodes de tableau dans les coulisses et les a intégrées au système réactif de Vue.</p> <p> Pouvons-nous faire quelque chose de similaire à LocalStorage?</p> <h3 id="Réécrivez-la-fonction-localstorage"> Réécrivez la fonction localstorage</h3> <p> Tout d'abord, nous pouvons corriger notre exemple initial en remplaçant la méthode LocalStorage pour suivre les instances de composant demandées au projet LocalStorage.</p> <p> // Carte entre la clé du projet LocalStorage et la liste des instances de Vue qui en dépendent const StogeTitemSubScrirs = {};</p> <p> const getitem = window.localstorage.getItem; localStorage.getItem = (key, cible) => {console.info ("get", key);</p> <p> // Collectez les instances VUE dépendantes si (! StoreItemSubScripteurs [KEY]) StoreItemSubScribers [Key] = []; if (cible) StoreItemSubscrirs [clé] .push (cible);</p> <p> // appelle la fonction d'origine return getItem.call (localStorage, key); };</p> <p> const setItem = window.localstorage.setItem; localStorage.SetItem = (key, valeur) => {console.info ("paramètre", clé, valeur);</p> <p> // Mette à jour la valeur dans l'instance Vue qui dépend de if (StoreItemSubScribers [key]) {StoreItemSubScribers [key] .ForEach ((dep) => {if (dep.hasownproperty (key)) dep [key] = value;}); }</p> <p> // appelle la fonction originale setItem.call (localStorage, key, valeur); };</p> <p> // ... (le reste du code est le même que le texte d'origine)</p> <p> Dans cet exemple, nous avons redéfini <code>getItem</code> et <code>setItem</code> pour collecter et informer les composants qui dépendent des projets locaux. Dans le nouveau <code>getItem</code> nous enregistrons quel composant demande quel élément, et dans <code>setItem</code> nous contactons tous les composants qui demandent l'élément et réécrivons ses propriétés de données.</p> <p> Pour que le code ci-dessus fonctionne, nous devons transmettre une référence à l'instance de composant pour <code>getItem</code> , qui modifie sa signature de fonction. Nous ne pouvons plus utiliser la fonction Arrow, sinon nous n'aurons pas la bonne valeur de <code>this</code> .</p> <p> Si nous voulons faire mieux, nous devons creuser plus profondément. Par exemple, comment suivre les dépendances sans les passer explicitement?</p> <h3 id="Comment-collecter-les-dépendances-dans-Vue"> Comment collecter les dépendances dans Vue</h3> <p> Pour l'inspiration, nous pouvons revenir au système réactif de Vue. Nous avons déjà vu que lors de l'accès à une propriété de données, le Getter de la propriété de données souscrit à l'appelant pour poursuivre les modifications de cette propriété. Mais comment sait-il qui a fait l'appel? Lorsque nous obtenons l'attribut de données, sa fonction Getter n'a aucune entrée sur qui est l'appelant. La fonction Getter n'a aucune entrée. Comment sait-il à qui s'inscrire en tant que dépendance?</p> <p> Chaque attribut de données maintient une liste de ses dépendances qui doivent réagir dans une classe <code>Dep</code> . Si nous approfondissons cette classe, nous pouvons voir que chaque fois qu'une dépendance est enregistrée, la dépendance elle-même est déjà définie dans une variable cible statique. Jusqu'à présent, cet objectif est fixé par une mystérieuse classe <code>Watcher</code> . En fait, lorsque les propriétés de données changent, ces observateurs seront en fait informés qu'ils initieront la réinstallation des composants ou la recommandation des propriétés calculées.</p> <p> Mais, encore une fois, qui sont-ils?</p> <p> Lorsque Vue rend l'option de données observable, elle crée également des observateurs pour chaque fonction d'attribut calculée ainsi que toutes les fonctions d'observation (qui ne doivent pas être confondues avec <code>Watcher</code> ) et la fonction de rendu pour chaque instance de composant. L'observateur est comme un compagnon de ces fonctions. Ils font deux choses principales:</p> <ol> <li> <strong>Ils évaluent les fonctions au moment de la création.</strong> Cela déclenche la collection de dépendances.</li> <li> <strong>Lorsqu'ils sont informés que la valeur sur laquelle ils dépendent ont changé, ils relaient leurs fonctions.</strong> Cela recalculera éventuellement les propriétés calculées ou renforcera l'ensemble du composant.</li> </ol> <p> Une étape importante se produit avant que l'observateur appelle les fonctions dont ils sont responsables: <strong>ils se définissent comme des cibles dans des variables statiques dans <code>Dep</code> .</strong> Cela garantit que lorsque les attributs de données réactifs sont accessibles, ils sont enregistrés en tant que dépendances.</p> <h3 id="Track-qui-a-appelé-localstorage"> Track qui a appelé localstorage</h3> <p> Nous ne pouvons pas le faire complètement parce que nous ne pouvons pas accéder aux mécanismes internes de Vue. Cependant, nous pouvons utiliser l'idée de Vue pour laisser l'observateur définir la cible dans une propriété statique avant d'appeler la fonction dont elle est responsable. Pouvons-nous définir une référence à l'instance du composant avant d'appeler LocalStorage?</p> <p> Si nous supposons que LocalStorage est appelé lors de la définition d'options de données, nous pouvons nous accrocher pour <code>beforeCreate</code> et <code>created</code> . Ces deux crochets sont tirés avant et après l'initialisation de l'option de données, nous pouvons donc le définir, puis effacer une variable cible avec une référence à l'instance de composante actuelle (nous pouvons y accéder dans le crochet de cycle de vie). Ensuite, dans notre Getter personnalisé, nous pouvons enregistrer cet objectif en tant que dépendance.</p> <p> La dernière chose que nous devons faire est de faire de ces crochets de cycle de vie une partie de tous nos composants. Nous pouvons le faire en utilisant Global Mixin pour l'ensemble du projet.</p> <p> // ... (le reste du code est le même que le texte d'origine)</p> <p> Maintenant, lorsque nous exécutons l'exemple initial, nous obtiendrons un compteur qui augmenterons le nombre par seconde.</p> <p> // ... (le reste du code est le même que le texte d'origine)</p> <h3 id="La-fin-de-notre-expérience-de-pensée"> La fin de notre expérience de pensée</h3> <p> Bien que nous résurions le problème initial, n'oubliez pas qu'il s'agit principalement d'une expérience de pensée. Il manque certaines fonctionnalités, telles que la gestion des projets supprimés et des instances de composants désinstallées. Il a également certaines limites, telles que le nom de propriété de l'instance de composant doit être la même que le nom du projet stocké dans LocalStorage. Cela dit, l'objectif principal est de mieux comprendre comment les systèmes réactifs vue fonctionnent dans les coulisses et en profiter, donc j'espère que c'est ce que vous en tirez.</p></keys.length>
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds











Avez-vous déjà eu besoin d'un compte à rebours sur un projet? Pour quelque chose comme ça, il pourrait être naturel d'atteindre un plugin, mais c'est en fait beaucoup plus

Tout ce que vous avez toujours voulu savoir sur les attributs de données dans HTML, CSS et JavaScript.

Au début d'un nouveau projet, la compilation SASS se produit en un clin d'œil. Cela se sent bien, surtout quand il est associé à BrowSersync, qui recharge

Une chose qui a attiré mon œil sur la liste des fonctionnalités pour le polyfill à gradient conique () de Lea.

Essayons de savoir un terme ici: "fournisseur de formulaire statique". Vous apportez votre HTML

La directive en ligne en ligne nous permet de construire des composants Vue riches en tant qu'amélioration progressive par rapport au balisage WordPress existant.

Chaque fois que je commence un nouveau projet, j'organise le code que je regarde en trois types ou catégories si vous le souhaitez. Et je pense que ces types peuvent être appliqués à

Les modèles PHP obtiennent souvent un mauvais rap pour faciliter le code inférieur - mais cela ne doit pas être le cas. Voyons comment les projets PHP peuvent appliquer un base
