Table des matières
Pour implémenter le calcul
Maison interface Web Voir.js Comment implémenter le calcul dans le système réactif Vue3

Comment implémenter le calcul dans le système réactif Vue3

May 15, 2023 pm 01:13 PM
vue3 computed

Tout d'abord, passons brièvement en revue :

Le cœur du système réactif est une WeakMap --- Map --- Set structure de données.

Comment implémenter le calcul dans le système réactif Vue3

La clé de WeakMap est l'objet d'origine et la valeur est la carte réactive. De cette façon, lorsque l’objet est détruit, la Carte correspondante sera également détruite. La clé de

Map est chaque attribut de l'objet, et la valeur est un ensemble de fonctions d'effet qui dépendent des attributs de cet objet. Utilisez ensuite la méthode get de l'objet proxy Proxy pour collecter les fonctions d'effet qui dépendent des propriétés de l'objet dans le Set correspondant à la clé. Il est également nécessaire de proxy la méthode set de l'objet et d'appeler toutes les fonctions d'effet de la clé lors de la modification des propriétés de l'objet.

Dans le dernier article, nous avons implémenté un système réactif relativement complet basé sur cette idée, et aujourd'hui nous continuons à implémenter le calcul.

Pour implémenter le calcul

Tout d'abord, nous reconstruisons le code précédent et séparons la collection de dépendances et déclenchons l'exécution des fonctions de dépendance en fonctions de suivi et de déclenchement :

Comment implémenter le calcul dans le système réactif Vue3

La logique est toujours d'ajouter des effets au Set correspondant, En plus de déclencher l'exécution de la fonction d'effet dans le Set correspondant, mais il est beaucoup plus clair de l'extraire.

Ensuite, continuez à mettre en œuvre le calcul. L'utilisation de

calculed ressemble à ceci :

const value = computed(() => {
    return obj.a + obj.b;
});
Copier après la connexion

Comparez l'effet :

effect(() => {
    console.log(obj.a);
});
Copier après la connexion

La différence n'est qu'une valeur de retour supplémentaire.

Nous implémentons donc un calcul basé sur un effet comme celui-ci :

function computed(fn) {
    const value = effect(fn);
   return value
}
Copier après la connexion

Bien sûr, l'effet actuel n'a pas de valeur de retour, nous devons l'ajouter :

Comment implémenter le calcul dans le système réactif Vue3

C'est juste basé sur l'exécution précédente du fonction d'effet Enregistrez la valeur de retour et renvoyez-la. Cette transformation est toujours très simple.

Maintenant, calculé peut renvoyer la valeur calculée :

Comment implémenter le calcul dans le système réactif Vue3

Mais maintenant les données sont transmises, tous les effets sont exécutés, et les effets comme calculés ici n'ont pas besoin d'être réexécutés à chaque fois, juste exécutés après les données ont changé.

Nous ajoutons donc une option paresseuse pour contrôler que l'effet ne soit pas exécuté immédiatement, mais pour renvoyer la fonction et laisser l'utilisateur l'exécuter lui-même.

Comment implémenter le calcul dans le système réactif Vue3

Ensuite, lorsque vous utilisez l'effet dans le calcul, ajoutez une option paresseuse pour que la fonction d'effet ne s'exécute pas mais retourne.

Créez un objet calculé, appelez cette fonction lorsque la valeur get est déclenchée pour obtenir la dernière valeur :

Comment implémenter le calcul dans le système réactif Vue3

Testons-la :

Comment implémenter le calcul dans le système réactif Vue3

Vous pouvez voir la valeur renvoyée par calculé maintenant. L'attribut peut obtenir la valeur calculée, et après avoir modifié obj.a., la fonction de calcul sera réexécutée et la nouvelle valeur pourra être obtenue lorsque la valeur sera à nouveau obtenue.

Effectuez simplement un calcul supplémentaire. En effet, toutes les fonctions d'effet seront exécutées lorsque obj.a change :

Comment implémenter le calcul dans le système réactif Vue3

De cette façon, chaque fois que les données changent, la fonction calculée sera réexécutée pour calculer. la dernière valeur.

Ce n'est pas nécessaire. Que la fonction d'effet soit exécutée ou non doit être contrôlable. Nous devons donc y ajouter la fonction de planification :

Comment implémenter le calcul dans le système réactif Vue3

peut prendre en charge la transmission de la fonction de rappel schduler, puis lors de l'exécution de l'effet, s'il existe un planificateur, transmettez-le-lui et laissez l'utilisateur le planifier. lui-même, sinon la fonction d'effet sera exécutée.

Pour que les utilisateurs puissent contrôler eux-mêmes l'exécution de la fonction d'effet :

Comment implémenter le calcul dans le système réactif Vue3

Ensuite, essayez le code tout de suite :

Comment implémenter le calcul dans le système réactif Vue3

Vous pouvez voir que l'effet n'est pas exécuté après que obj.a soit a changé la fonction pour recalculer, car nous avons ajouté un planificateur pour le planifier nous-mêmes. Cela évite d'avoir à exécuter la fonction calculée immédiatement après les modifications des données et vous pouvez contrôler l'exécution vous-même.

Maintenant, il y a un autre problème, res.value doit être calculé à chaque accès :

Comment implémenter le calcul dans le système réactif Vue3

能不能加个缓存呢?只有数据变了才需要计算,否则直接拿之前计算的值。

当然是可以的,加个标记就行:

Comment implémenter le calcul dans le système réactif Vue3

scheduler 被调用的时候就说明数据变了,这时候 dirty 设置为 true,然后取 value 的时候就重新计算,之后再改为 false,下次取 value 就直接拿计算好的值了。

我们测试下:

Comment implémenter le calcul dans le système réactif Vue3

我们访问 computed 值的 value 属性时,第一次会重新计算,后面就直接拿计算好的值了。

修改它依赖的数据后,再次访问 value 属性会再次重新计算,然后后面再访问就又会直接拿计算好的值了。

至此,我们完成了 computed 的功能。

但现在的 computed 实现还有一个问题,比如这样一段代码:

let res = computed(() => {
    return obj.a + obj.b;
});
effect(() => {
    console.log(res.value);
});
Copier après la connexion

我们在一个 effect 函数里用到了 computed 值,按理说 obj.a 变了,那 computed 的值也会变,应该触发所有的 effect 函数。

但实际上并没有:

Comment implémenter le calcul dans le système réactif Vue3

这是为什么呢?

这是因为返回的 computed 值并不是一个响应式的对象,需要把它变为响应式的,也就是 get 的时候 track 收集依赖,set 的时候触发依赖的执行:

Comment implémenter le calcul dans le système réactif Vue3

我们再试一下:

Comment implémenter le calcul dans le système réactif Vue3

现在 computed 值变了就能触发依赖它的 effect 了。至此,我们的 computed 就很完善了。

完整代码如下:

const data = {
    a: 1,
    b: 2
}
let activeEffect
const effectStack = [];
function effect(fn, options = {}) {
  const effectFn = () => {
      cleanup(effectFn)
      activeEffect = effectFn
      effectStack.push(effectFn);
      const res = fn()
      effectStack.pop()
      activeEffect = effectStack[effectStack.length - 1]
      return res
  }
  effectFn.deps = []
  effectFn.options = options;
  if (!options.lazy) {
    effectFn()
  }
  return effectFn
}
function computed(fn) {
    let value
    let dirty = true
    const effectFn = effect(fn, {
        lazy: true,
        scheduler(fn) {
            if(!dirty) {
                dirty = true
                trigger(obj, 'value');
            }
        }
    });
    const obj = {
        get value() {
            if (dirty) {
                value = effectFn()
                dirty = false
            }
            track(obj, 'value');
            console.log(obj);
            return value
        }
    }
    return obj
}
function cleanup(effectFn) {
    for (let i = 0; i < effectFn.deps.length; i++) {
        const deps = effectFn.deps[i]
        deps.delete(effectFn)
    }
    effectFn.deps.length = 0
}
const reactiveMap = new WeakMap()
const obj = new Proxy(data, {
    get(targetObj, key) {
        track(targetObj, key);

        return targetObj[key]
   },
   set(targetObj, key, newVal) {
        targetObj[key] = newVal

        trigger(targetObj, key)
    }
})
function track(targetObj, key) {
    let depsMap = reactiveMap.get(targetObj)
    if (!depsMap) {
    reactiveMap.set(targetObj, (depsMap = new Map()))
    }
    let deps = depsMap.get(key)
    if (!deps) {
    depsMap.set(key, (deps = new Set()))
    }
    deps.add(activeEffect)
    activeEffect.deps.push(deps);
}
function trigger(targetObj, key) {
    const depsMap = reactiveMap.get(targetObj)
    if (!depsMap) return
    const effects = depsMap.get(key)
    const effectsToRun = new Set(effects)
    effectsToRun.forEach(effectFn => {
        if(effectFn.options.scheduler) {
            effectFn.options.scheduler(effectFn)
        } else {
            effectFn()
        }
    })
}
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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

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 !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

Comment utiliser tinymce dans le projet vue3 Comment utiliser tinymce dans le projet vue3 May 19, 2023 pm 08:40 PM

tinymce est un plug-in d'éditeur de texte riche entièrement fonctionnel, mais l'introduction de tinymce dans vue n'est pas aussi fluide que les autres plug-ins de texte riche de Vue. tinymce lui-même ne convient pas à Vue, et @tinymce/tinymce-vue doit être introduit, et Il s'agit d'un plug-in de texte riche étranger et n'a pas passé la version chinoise. Vous devez télécharger le package de traduction depuis son site officiel (vous devrez peut-être contourner le pare-feu). 1. Installez les dépendances associées npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2. Téléchargez le package chinois 3. Introduisez le skin et le package chinois Créez un nouveau dossier tinymce dans le dossier public du projet et téléchargez le.

vue3+vite : Comment résoudre l'erreur lors de l'utilisation de require pour importer dynamiquement des images dans src vue3+vite : Comment résoudre l'erreur lors de l'utilisation de require pour importer dynamiquement des images dans src May 21, 2023 pm 03:16 PM

vue3+vite:src utilise require pour importer dynamiquement des images et des rapports d'erreurs et des solutions. vue3+vite importe dynamiquement plusieurs images. Si vue3 est développé à l'aide de TypeScript, il y aura un message d'erreur indiquant que requireisnotdefined ne peut pas être utilisé comme imgUrl. :require(' .../assets/test.png') est importé car TypeScript ne prend pas en charge require, donc l'importation est utilisée. Voici comment le résoudre : utilisez waitimport.

Comment actualiser le contenu partiel de la page dans Vue3 Comment actualiser le contenu partiel de la page dans Vue3 May 26, 2023 pm 05:31 PM

Pour réaliser un rafraîchissement partiel de la page, il suffit d'implémenter le re-rendu du composant local (dom). Dans Vue, le moyen le plus simple d'obtenir cet effet est d'utiliser la directive v-if. Dans Vue2, en plus d'utiliser l'instruction v-if pour restituer le dom local, nous pouvons également créer un nouveau composant vierge. Lorsque nous devons actualiser la page locale, accéder à cette page de composant vierge, puis y revenir. la garde beforeRouteEnter dans la page d’origine vierge. Comme le montre la figure ci-dessous, comment cliquer sur le bouton d'actualisation dans Vue3.X pour recharger le DOM dans la zone rouge et afficher l'état de chargement correspondant. Puisque la garde dans le composant dans la syntaxe scriptsetup dans Vue3.X n'a ​​que o

Comment Vue3 analyse le démarque et implémente la mise en évidence du code Comment Vue3 analyse le démarque et implémente la mise en évidence du code May 20, 2023 pm 04:16 PM

Pour implémenter le front-end du blog avec Vue, vous devez implémenter l'analyse markdown. S'il y a du code, vous devez implémenter la mise en évidence du code. Il existe de nombreuses bibliothèques d'analyse de démarques pour Vue, telles que markdown-it, vue-markdown-loader, Markdown, vue-markdown, etc. Ces bibliothèques sont toutes très similaires. Marked est utilisé ici et highlight.js est utilisé comme bibliothèque de mise en évidence du code. Les étapes d'implémentation spécifiques sont les suivantes : 1. Installez les bibliothèques dépendantes. Ouvrez la fenêtre de commande sous le projet vue et entrez la commande suivante npminstallmarked-save//marked pour convertir le markdown en htmlnpmins.

Comment utiliser vue3+ts+axios+pinia pour obtenir un rafraîchissement insensé Comment utiliser vue3+ts+axios+pinia pour obtenir un rafraîchissement insensé May 25, 2023 pm 03:37 PM

vue3+ts+axios+pinia réalise un rafraîchissement insensé 1. Téléchargez d'abord aiXos et pinianpmipinia dans le projet--savenpminstallaxios--save2 Encapsuler la requête axios-----Télécharger js-cookienpmiJS-cookie-s//Introduire aixosimporttype{AxiosRequestConfig , AxiosResponse}de"axios";importaxiosfrom'axios';import{ElMess

Comment sélectionner un avatar et le recadrer dans Vue3 Comment sélectionner un avatar et le recadrer dans Vue3 May 29, 2023 am 10:22 AM

L'effet final est d'installer le composant VueCropper filaddvue-cropper@next. La valeur d'installation ci-dessus est pour Vue3 ou si vous souhaitez utiliser d'autres méthodes de référence, veuillez visiter son adresse officielle npm : tutoriel officiel. Il est également très simple de le référencer et de l'utiliser dans un composant. Il suffit d'introduire le composant correspondant et son fichier de style. Je ne le référence pas globalement ici, mais j'introduis uniquement import{userInfoByRequest}from'../js/api. ' dans mon fichier de composant import{VueCropper}from'vue-cropper&.

Comment utiliser les composants réutilisables Vue3 Comment utiliser les composants réutilisables Vue3 May 20, 2023 pm 07:25 PM

Préface Que ce soit vue ou réagir, lorsque nous rencontrons plusieurs codes répétés, nous réfléchirons à comment réutiliser ces codes, au lieu de remplir un fichier avec un tas de codes redondants. En fait, Vue et React peuvent être réutilisés en extrayant des composants, mais si vous rencontrez quelques petits fragments de code et que vous ne souhaitez pas extraire un autre fichier, en comparaison, React peut être utilisé dans le même Déclarez le widget correspondant dans le fichier. , ou implémentez-le via la fonction de rendu, telle que : constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(

Comment utiliser definitionCustomElement pour définir des composants dans Vue3 Comment utiliser definitionCustomElement pour définir des composants dans Vue3 May 28, 2023 am 11:29 AM

Utilisation de Vue pour créer des éléments personnalisés WebComponents est un nom collectif pour un ensemble d'API Web natives qui permettent aux développeurs de créer des éléments personnalisés réutilisables (customelements). Le principal avantage des éléments personnalisés est qu’ils peuvent être utilisés avec n’importe quel framework, même sans. Ils sont idéaux lorsque vous ciblez des utilisateurs finaux susceptibles d'utiliser une pile technologique frontale différente, ou lorsque vous souhaitez dissocier l'application finale des détails d'implémentation des composants qu'elle utilise. Vue et WebComponents sont des technologies complémentaires et Vue offre un excellent support pour l'utilisation et la création d'éléments personnalisés. Vous pouvez intégrer des éléments personnalisés dans des applications Vue existantes ou utiliser Vue pour créer

See all articles