keepalive は vue3 のグローバル コンポーネントです
keepalive 自体はレンダリングされず、表示されません。ノードですが、vnode としてレンダリングされます。キープアライブ内のキャッシュとキーは、vnode を通じて追跡できます。もちろん、これは開発環境でのみ可能です。ビルドがパッケージ化された後は、vnode には公開されません(これは再度確認する必要があります)
キープアライブの最も重要な機能はコンポーネントをキャッシュすることです
<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, 'this.caches') this.caches = this.caches.filter((item: any) => item !== name); console.log(this.caches, 'this.caches') }, 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 === 'Home' && to.name === 'record-month') { 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('.van-pull-refresh') dom!.scrollTop = value }
A useThrottleFn は上記の登録スクロール イベントで使用されており、このクラス ライブラリは @vueuse/core で提供されており、多くのツールがカプセル化されており、非常に優れています。興味がある場合は、勉強してください
onMounted(() => { scrollDom.value = document.querySelector('.van-pull-refresh') as HTMLElement const throttledFun = useThrottleFn(() => { console.log(scrollDom.value?.scrollTop, 'addEventListener') state.scrollTop = scrollDom.value!.scrollTop }, 500) if(scrollDom.value) { scrollDom.value.addEventListener('scroll',throttledFun) } }) const getScrollTop = () => { console.log('scrollDom.vaue', 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 }
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 をクリックして、レンダリング関数を再度実行します
次に、コンポーネントをクリックします。次に、レンダリング関数が再度実行されます。
<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: 'Demo1', template: '#template-1', setup(props) { } } const Demo2 = { name: 'Demo2', template: '#template-2', 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: '', componentName: '', }), methods:{ changeClick(type) { if(type === 1) { if(!this.includeCache.includes('Demo1')) { this.includeCache.push('Demo1') } console.log(this.includeCache, '000') this.componentCache = Demo1 this.componentName = 'Demo1' } if(type === 2) { if(!this.includeCache.includes('Demo2')) { this.includeCache.push('Demo2') } console.log(this.includeCache, '2222') this.componentName = 'Demo2' this.componentCache = Demo2 } } } }).mount('#demo') </script>
以上がvue3 キープアライブのオンライン問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。