Maison  >  Article  >  interface Web  >  Comment résoudre les problèmes en ligne de Vue3 Keepalive

Comment résoudre les problèmes en ligne de Vue3 Keepalive

王林
王林avant
2023-05-19 08:04:12971parcourir

1, la fonction keepalive

  • keepalive est un composant global dans vue3

  • keepalive lui-même ne sera pas rendu ou n'apparaîtra pas dans le nœud DOM, mais il sera rendu en tant que vnode. Le cache et les clés de keepalive peuvent être suivis via le vnode. Bien sûr, cela n'est possible que dans l'environnement de développement. emballé, il n'est pas exposé au vnode (Cela doit être confirmé à nouveau)

  • keepalive La fonction la plus importante est le composant cache

    #🎜🎜 #
  • keepalive Pass La stratégie d'expulsion du cache LRU met à jour le cache des composants, ce qui peut utiliser la mémoire plus efficacement et empêcher le débordement de mémoire. Le nombre maximum de caches dans le code source est de 10, c'est-à-dire après 10 composants. , le premier composant mis en cache sera éliminé.#🎜 🎜#

  • 2 Scénarios d'utilisation de Keepalive

    Supposons un scénario. : La page A est la page d'accueil ====== > Page de liste des pages B (pages qui doivent être mises en cache) ======> Lorsque la page de détails C passe de la page de détails C à la page B, il doit revenir à la page de cache B, y compris les données de base et la liste de la page. Si les informations sur la position de la barre de défilement sont renvoyées de la page B à la page A, la page de cache de B doit être vidée
  • Un autre scénario ci-dessus : entrez dans la page et mettez-la directement en cache, et là C'est fini, c'est relativement simple et je n'en parlerai pas dans cet article #
  • Le composant keepalive a un. un total de trois paramètres

include : les chaînes, les expressions régulières et les tableaux peuvent être transmis, et les composants dont le nom correspond avec succès seront mis en cache#🎜 🎜#

exclude : les chaînes, les expressions régulières et les tableaux peuvent être transmis, les composants dont le nom correspond avec succès ne seront pas mis en cacheComment résoudre les problèmes en ligne de Vue3 Keepalive

#🎜 🎜#max : numéro transmissible, limitant le nombre maximum de composants mis en cache, la valeur par défaut est 10

  • Ajoutez et introduisez d'abord le composant keepalive dans le code racine d'App.vue, via ici vous pouvez trouver que ce que je cache ici équivaut à la page entière. Bien sûr, vous pouvez également contrôler un certain composant de zone de la page de manière plus fine (vuex utilisé dans ) pour enregistrer le composant de page à mettre en cache, pour gérer l'inclusion. cache et pour enregistrer les données d'informations de la barre de défilement dans le composant de page

        <template>
            <router-view v-slot="{ Component }">
                <keep-alive :include="keepAliveCache">
                    <component :is="Component" :key="$route.name" />
                </keep-alive>
            </router-view>
        </template>
        <script lang="ts" setup>
        import { computed } from "vue";
        import { useKeepAliverStore } from "@/store";
        const useStore = useKeepAliverStore();
        const keepAliveCache = computed(() => {
            return useStore.caches;
        });
        </script>
  • Lorsque l'itinéraire du composant vient d'être changé, écrivez le composant à inclure via beforeRouteEnter, À ce stade, le cycle de vie du composant n'a pas encore commencé. Si l'exécution du cycle de vie du composant a déjà commencé, il est logique de réécrire.
  • Cette fonction hook ne peut donc pas être écrite dans le setup et doit être écrite séparément. Bien sûr, vous pouvez également passer à d'autres fonctions de hook de routage à gérer avantEach, mais si vous l'utilisez ici, il semble que pinia ne puisse pas être utilisé. Cela nécessite des recherches plus approfondies.

        import { defineStore } from "pinia";
        export const useKeepAliverStore = defineStore("useKeepAliverStore", {
            state: () => ({
                caches: [] as any,
                scrollList: new Map(),  // 缓存页面组件如果又滚动条的高度
            }),
            actions: {
                add(name: string) {
                    this.caches.push(name);
                },
                remove(name: string) {
                    console.log(this.caches, &#39;this.caches&#39;)
                    this.caches = this.caches.filter((item: any) => item !== name);
                    console.log(this.caches, &#39;this.caches&#39;)
                },
                clear() {
                    this.caches = []
                }
            }
        });
  • Lorsque la route du composant quitte, il est jugé s'il faut sortir du cache. Ce hook peut être écrit directement dans la configuration.
  •     import { useRoute, useRouter, onBeforeRouteLeave } from "vue-router";
        import { useKeepAliverStore } from "@/store";
        const useStore = useKeepAliverStore()
        export default {
            name:"record-month",
            beforeRouteEnter(to, from, next) {
                next(vm => {
                    if(from.name === &#39;Home&#39; && to.name === &#39;record-month&#39;) {
                    useStore.add(to.name)
                    }
                });
            }
        }
        </script>

    Le cache de la position de défilement est traité dans les deux fonctions hook de keepalive. La position dans le cache est obtenue dans onActivated, et la position dans le cache est enregistrée dans onDeactivated.

        onBeforeRouteLeave((to, from) => {
            console.log(to.name, "onBeforeRouteLeave");
            if (to.name === "new-detection-detail") {
                console.log(to, from, "进入详情页面不做处理");
            } else {
                useStore.remove(from.name)
                console.log(to, from, "删除组件缓存");
            }
        });

    Une méthode est définie ici, le paramètre scrollTop utilise l'API javascript native
  •     onActivated(() => {
            if(useStore.scrollList.get(routeName)) {
                const top = useStore.scrollList.get(routeName)
                refList.value.setScrollTop(Number(top))
            }
        });
        onDeactivated(() => {
            const top = refList.value.getScrollTop()
            useStore.scrollList.set(routeName, top)
        });
En même temps, comment obtenir la hauteur consiste d'abord à enregistrer l'événement de défilement, puis à obtenir le courant position de la barre de défilement via getScrollTop et enregistrez-la

    const setScrollTop = (value: any) => {
        const dom = document.querySelector(&#39;.van-pull-refresh&#39;)
        dom!.scrollTop = value
    }

Above Un useThrottleFn est utilisé pour enregistrer l'événement de défilement. Cette bibliothèque de classes est fournie dans @vueuse/core. Elle encapsule de nombreux outils qui sont très bons. êtes intéressé, vous pouvez l'étudier

    onMounted(() => {
        scrollDom.value = document.querySelector(&#39;.van-pull-refresh&#39;) as HTMLElement
        const throttledFun = useThrottleFn(() => {
            console.log(scrollDom.value?.scrollTop, &#39;addEventListener&#39;)
            state.scrollTop = scrollDom.value!.scrollTop
        }, 500)
        if(scrollDom.value) {
            scrollDom.value.addEventListener(&#39;scroll&#39;,throttledFun)
        }
    })
    const getScrollTop = () => {
        console.log(&#39;scrollDom.vaue&#39;, scrollDom.value?.scrollTop)
        return state.scrollTop
    }

Vous pouvez également le consulter à ce moment-là. Trouvez le vnode de l'instance et trouvez le keepalive, qui se trouve dans le sous-composant à côté du keepalive

    https://vueuse.org/shared/usethrottlefn/#usethrottlefn

4, débogage du code source de vue3 keepalive

1, code de clonage

    const instance = getCurrentInstance()
    console.log(instance.vnode.parent) // 这里便是keepalive组件vnode
    // 如果是在开发环境中可以查看到cache对象
    instance.vnode.parent.__v_cache
    // vue源码中,在dev环境对cache进行暴露,生产环境是看不到的
    if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
        ;(instance as any).__v_cache = cache
    }

2 Installez les dépendances

    git clone git@github.com:vuejs/core.git

3. utilisez pnpm, vous pouvez d'abord l'installer via npm

    pnpm i

4 Une fois l'installation terminée, recherchez le package du répertoire racine Les scripts dans le fichier json

    npm i pnpm -g

Référence https. ://www.yisu.com/article/154583.htm

5. L'exécution de pnpm run dev construira le code source de vue# 🎜🎜#
    // 在dev命令后添加 --source-map是从已转换的代码,映射到原始的源文件
    "dev": "node scripts/dev.js  --sourcemap"

6. html dans....corepackagesvueexamplescomposition, copiez le code suivant, puis ouvrez-le via le navigateur Chrome, F12, recherchez la page à onglets du code source et utilisez la touche de raccourci Ctrl+P Entrez KeepAlive pour rechercher ce composant, puis faites un clic droit sur la marque de ligne à gauche pour ajouter un point d'arrêt pour le débogage. Vous pouvez également utiliser la [Pile d'appels] à droite pour accéder rapidement au code pour le débogage.

    pnpm run dev
    //则会出现以下,代表成功了(2022年5月27日),后期vue源代码作者可能会更新,相应的提示可能发生变更,请注意一下
    > @3.2.36 dev H:\github\sourceCode\core
    > node scripts/dev.js  --sourcemap
    watching: packages\vue\dist\vue.global.js
    //到..\..\core\packages\vue\dist便可以看到编译成功,以及可以查看到examples样例demo页面

7. Le débogage du code source a révélé que la fonction de rendu dans keepalive (ou la fonction de retour dans la configuration) sera exécutée lorsque le sous-composant est commuté, modifiant ainsi le cache logique#🎜🎜 #

La première fois que vous entrez dans la page pour initialiser le composant keepalive sera exécuté une fois,

Cliquez ensuite sur le composant un et exécutez à nouveau la fonction de rendu

# 🎜🎜#

Cliquez ensuite sur le composant deux, la fonction de rendu sera à nouveau exécutée

#🎜 🎜#8. Instructions de capture d'écran de débogage

    5. Analyse approximative du code source de vue3 keealive
  • En visualisant le KeepAlive de vue3. code source ts

        <script src="../../dist/vue.global.js"></script>
        <script type="text/x-template" id="template-1">
            <div>template-1</div>
            <div>template-1</div>
        </script>
        <script type="text/x-template" id="template-2">
            <div>template-2</div>
            <div>template-2</div>
        </script>
        <script>
        const { reactive, computed } = Vue
        const Demo1 = {
            name: &#39;Demo1&#39;,
            template: &#39;#template-1&#39;,
            setup(props) {
            }
        }
        const Demo2 = {
            name: &#39;Demo2&#39;,
            template: &#39;#template-2&#39;,
            setup(props) {
            }
        }
        </script>
        <!-- App template (in DOM) -->
        <div id="demo">
            <div>Hello World</div>
            <div>Hello World</div>
            <div>Hello World</div>
            <button @click="changeClick(1)">组件一</button>
            <button @click="changeClick(2)">组件二</button>
            <keep-alive :include="includeCache">
                <component :is="componentCache" :key="componentName" v-if="componentName" />
            </keep-alive>
        </div>
        <!-- App script -->
        <script>
        Vue.createApp({
        components: {
            Demo1,
            Demo2
        },
        data: () => ({
            includeCache: [],
            componentCache: &#39;&#39;,
            componentName: &#39;&#39;,
        }),
        methods:{
            changeClick(type) {
                if(type === 1) {
                    if(!this.includeCache.includes(&#39;Demo1&#39;)) {
                        this.includeCache.push(&#39;Demo1&#39;)
                    }
                    console.log(this.includeCache, &#39;000&#39;)
                    this.componentCache = Demo1
                    this.componentName = &#39;Demo1&#39;
                }
                if(type === 2) {
                    if(!this.includeCache.includes(&#39;Demo2&#39;)) {
                        this.includeCache.push(&#39;Demo2&#39;)
                    }
                    console.log(this.includeCache, &#39;2222&#39;)
                    this.componentName = &#39;Demo2&#39;
                    this.componentCache = Demo2
                }
            }
        }
        }).mount(&#39;#demo&#39;)
        </script>

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer