>웹 프론트엔드 >View.js >vue3 keepalive 온라인 문제를 해결하는 방법

vue3 keepalive 온라인 문제를 해결하는 방법

王林
王林앞으로
2023-05-19 08:04:121119검색

1. Keepalive 기능

  • keepalive는 vue3의 전역 구성 요소입니다

  • keepalive 자체는 렌더링되지 않으며 dom 노드에도 표시되지 않지만 vnode로 렌더링되며 이를 통해 추적할 수 있습니다. vnode Keepalive의 캐시와 키는 물론 개발 환경에서만 사용할 수 있습니다. 빌드 패키지 후에는 vnode에 노출되지 않습니다(이것은 다시 확인해야 합니다)

  • keepalive 가장 중요한 기능은 캐시 구성 요소입니다.

  • keepalive through LRU 캐시 제거 전략은 구성 요소 캐시를 업데이트하는 데 사용되며, 이를 통해 메모리를 보다 효율적으로 사용하고 메모리 오버플로를 방지할 수 있습니다. 소스 코드의 최대 캐시 수는 10개입니다. 즉, 구성 요소 10개 이후입니다.

2. Keepalive 사용 시나리오

  • 가정해 보겠습니다. A 페이지는 홈 페이지입니다. =====> 캐시됨) =======> C 세부정보 페이지 by C 세부정보 페이지가 B 페이지에 도달하면 페이지의 기본 데이터와 페이지의 스크롤바 위치 정보를 포함하여 B 캐시 페이지로 돌아가야 합니다. 목록 B 페이지에서 A 페이지로 돌아가면 B 캐시 페이지를 지워야 합니다

  • 위에서 언급한 또 다른 시나리오: 페이지에 들어가서 직접 캐시하면 이 작업은 비교적 간단하고 끝납니다.

3. 프로젝트의 사용 프로세스

vue3 keepalive 온라인 문제를 해결하는 방법

keepalive 구성요소에는 총 3개의 매개변수가 있습니다

  • include: 문자열, 정규식 및 배열이 전달될 수 있습니다. 성공적으로 일치하는 이름이 있는 구성 요소는 캐시됩니다.

  • 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)를 통해 캐시할 페이지 컴포넌트를 저장하여 include를 처리할 수 있습니다. 캐싱하고 페이지 컴포넌트에 스크롤 막대 정보 데이터를 저장합니다

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

컴포넌트 경로가 방금 전환되면 beforeRouteEnter를 통해 해당 컴포넌트를 include에 씁니다. 이때는 컴포넌트 수명 주기가 아직 시작되지 않았습니다. 컴포넌트 라이프사이클의 실행이 이미 시작된 경우 다시 작성하는 것이 좋습니다.

따라서 이 후크 기능은 설정에서 작성할 수 없고 별도로 작성해야 합니다. 물론 beforeEach를 처리하기 위해 라우팅의 다른 Hook 기능으로 전환할 수도 있지만 여기서 사용할 경우 pinia를 사용할 수 없는 것으로 보입니다.

    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>

컴포넌트 경로가 떠날 때 캐시 밖으로 이동할지 여부를 판단합니다. 이 후크는 설정에서 직접 작성할 수 있습니다.

    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, "删除组件缓存");
        }
    });

keepalive의 두 가지 후크 기능에 스크롤 위치를 캐시하고, onActivated에서 캐시의 위치를 ​​가져오고, onDeactivated에서 캐시의 위치를 ​​기록합니다.

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

네이티브 자바스크립트 API를 사용하여 scrollTop을 설정하는 메소드가 여기에 정의되어 있습니다

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

동시에 높이를 구하는 방법은? 먼저 스크롤 이벤트를 등록한 다음 getScrollTop을 통해 현재 스크롤 막대 위치를 가져와서 저장해야 합니다.

    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
    }

useThrottleFn은 위의 스크롤 이벤트를 등록하는 데 사용됩니다. 많은 도구들이 매우 훌륭하다는 것을 캡슐화한 @vueuse/core에 제공됩니다. 관심이 있으시면 공부해 보세요

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

이때 발견된 인스턴스의 vnode를 확인하여 에 있는 keepalive를 찾을 수도 있습니다. keepalive

    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
    }

4 옆에 있는 하위 구성 요소. Vue3 keepalive 소스 코드 디버깅

1, 코드를 복제합니다

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

2. pnpm을 사용할 수 없는 경우 먼저 npm을 통해 설치할 수 있습니다

    pnpm i
.

4. 설치가 완료되면 루트 디렉토리의 package.json 파일에서 스크립트를 찾으세요

    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....corepackagesvueexamplescomposition에 aehyok.html 파일을 추가하고 다음 코드를 추가합니다. 복사한 후 크롬 브라우저 F12를 통해 열고 소스의 탭 페이지를 찾습니다. 코드에서 단축키 Ctrl+P를 사용하여 KeepAlive를 입력하여 이 구성 요소를 찾은 다음 왼쪽의 선 표시를 마우스 오른쪽 버튼으로 클릭하여 디버깅을 위한 중단점을 추가하거나 오른쪽의 [Call Stack]을 사용하여 빠르게 이동합니다. 디버깅을 위한 코드입니다.

    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 소스 코드를 디버깅하면 하위 구성 요소가 전환될 때 keepalive의 렌더링 기능(또는 설정의 반환 기능)이 실행되어 로직 캐시가 변경되는 것으로 나타났습니다

    처음 입력할 때 Keepalive 구성 요소를 초기화하는 페이지가 실행됩니다. 일단,
  • 그런 다음 구성 요소 1을 클릭하고 렌더링 기능을 다시 실행합니다.
  • 그런 다음 구성 요소 2를 클릭하면 렌더링 기능이 다시 실행됩니다
  • 8. 디버깅 스크린샷 설명

vue3 keepalive 온라인 문제를 해결하는 방법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 keepalive 온라인 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제