ホームページ  >  記事  >  ウェブフロントエンド  >  vue3 キープアライブのオンライン問題を解決する方法

vue3 キープアライブのオンライン問題を解決する方法

王林
王林転載
2023-05-19 08:04:121025ブラウズ

1. Keepalive 関数

  • keepalive は vue3 のグローバル コンポーネントです

  • keepalive 自体はレンダリングされず、表示されません。ノードですが、vnode としてレンダリングされます。キープアライブ内のキャッシュとキーは、vnode を通じて追跡できます。もちろん、これは開発環境でのみ可能です。ビルドがパッケージ化された後は、vnode には公開されません(これは再度確認する必要があります)

  • キープアライブの最も重要な機能はコンポーネントをキャッシュすることです

  • ##キープアライブは LRU を通じてコン​​ポーネント キャッシュを更新しますキャッシュ削除戦略。メモリをより効果的に使用し、メモリ オーバーフローを防ぐことができます。ソース コード内のキャッシュの最大数は 10 です。つまり、コンポーネントが 10 個になった後、最初にキャッシュされたコンポーネントが削除され始めます

2. キープアライブの使用シナリオ

  • ここで次のシナリオを想定します: ページ A はホームページ =====> B ページ リスト ページ ( ======> C 詳細ページは、C 詳細ページが B ページに到達すると、ページの基本データとスクロール バーを含む B キャッシュ ページに戻る必要があります。リストの位置情報。B ページから A ページに戻る場合は、B キャッシュ ページをクリアする必要があります。

  • 上記の別のシナリオ: ページに入って直接キャッシュします。これは比較的単純なので、この記事では説明しません。

3. プロジェクトの使用プロセス

vue3 キープアライブのオンライン問題を解決する方法

キープアライブ コンポーネントには合計 3 つのパラメータがあります

  • 次のものが含まれます: 文字列、正規表現、配列、名前一致を渡すことができます成功したコンポーネントはキャッシュされます

  • exclude: 文字列、正規表現、配列を渡すことができます。名前一致が成功したコンポーネントはキャッシュされません

  • #max: 送信可能な数、キャッシュされる最大数を制限しますコンポーネント、デフォルトは 10
  • まず、App.vue ルート コードに keepalive コンポーネントを追加して導入します。ここで見つけることができます。私はここにいます。キャッシュはページ全体に相当します。もちろん、ページ内の特定の領域コンポーネントをより詳細に制御することもできます。
    <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>

は App.vue を通じて見つけられ、pinia (つまり、vue2 で使用される vuex) を通じて保存できます。キャッシュ対象のページコンポーネントは、インクルードキャッシュを処理し、ページコンポーネント内にスクロールバー情報データを保存するために使用されます。 . 現時点では、コンポーネントのライフサイクルはまだ開始されていません。コンポーネントのライフサイクルの実行がすでに始まっている場合は、再度記述するのが合理的です。

したがって、このフック関数はセットアップに記述することができないため、個別に記述する必要があります。もちろん、ルーティングの他のフック関数に切り替えて beforeEach を扱うこともできますが、ここで使うと pinia が使えないようなので、これは要研究です。

    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 = []
            }
        }
    });

コンポーネントルートが離脱する際にキャッシュ外に移動するかどうかを判定するフックです。このフックはセットアップに直接記述できます。

    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>

keepalive の 2 つのフック関数でスクロール位置キャッシュを処理します onActivated でキャッシュ上の位置を取得し、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, "删除组件缓存");
        }
    });

ここにメソッドを定義しますネイティブ JavaScript api

    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)
    });

高さを同時に取得するにはどうすればよいですか?まずスクロール イベントを登録し、次に getScrollTop を通じて現在のスクロール バーの位置を取得して保存する必要があります

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

A useThrottleFn は上記の登録スクロール イベントで使用されており、このクラス ライブラリは @vueuse/core で提供されており、多くのツールがカプセル化されており、非常に優れています。興味がある場合は、勉強してください

    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
    }

このとき、見つかったインスタンスの vnode をチェックしてキープアライブを見つけることもできます。キープアライブの隣のサブコンポーネント内です。

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

4、vue3 キープアライブ ソース コード デバッグ

1、クローン作成code

    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、インストールの依存関係

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

3、pnpmを使用できない場合は、npm first

    pnpm i

4を介してインストールできます。インストールが完了したら、ルート ディレクトリの package.json ファイル内の scripts

    npm i pnpm -g

参照 https://www.yisu .com/article/154583.htm

5. pnpm run dev を実行するとビルドされますvue ソース コード

    // 在dev命令后添加 --source-map是从已转换的代码,映射到原始的源文件
    "dev": "node scripts/dev.js  --sourcemap"

6。次に....\core\packages\vue\examples\composition に aehyok.html ファイルを追加し、次のコードをコピーして、Chrome ブラウザで開きます。 F12 キーを押してソース コードのタブ ページを見つけ、ショートカット キー Ctrl P を使用して KeepAlive と入力してこのコンポーネントを見つけ、左側の線マークを右クリックします。デバッグ用のブレークポイントを追加することも、すぐにジャンプすることもできます。右側の[呼び出しスタック]からデバッグするためのコード。

    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. ソース コードをデバッグすると、サブコンポーネントが切り替わるとキープアライブのレンダリング関数 (またはセットアップの return 関数) が実行され、ロジック キャッシュが変更されることがわかりました

最初にページに入ると、キープアライブ コンポーネントが 1 回実行されて初期化されます。

  • 次に、コンポーネント 1 をクリックして、レンダリング関数を再度実行します

  • 次に、コンポーネントをクリックします。次に、レンダリング関数が再度実行されます。

  • ##8. デバッグ スクリーンショットの説明

##5. vue3 keealive ソース コードの簡単な分析

vue3 KeepAlive.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>

以上がvue3 キープアライブのオンライン問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。