vue keep-alive(1): How vue router ensures that the page does not refresh when the page returns

When building SPA applications, a common scenario is that the list page jumps to the details page, but the details page returns to the list page, and the list page is refreshed.

How to ensure that the page is not refreshed when going back? keep-alive is a very good solution (of course you can also overwrite it with sub-routes and absolute positioning *_*).

The role of keep-alive

keep-alive is a built-in component of Vue that can retain the state in memory during component switching to prevent repeated rendering of the DOM.

This article mainly talks about the usage of keep-alive.

keep-alive usage

Load dynamic components like Tabs (some children's shoes directly use dynamic components to replace routing functions - personally not recommended)

Cache component

<keep-alive>
 <component include="a" exclude="b">
  <!-- The component with name a will be cached! ,The component with name b is not cached! -->
 </component>
</keep-alive>

cache route

<keep-alive include="a">
  <router-view>
    <!-- Only the view a component whose path matches the path will be cached! -->
  </router-view>
</keep-alive>

Recommended usage: No need to enumerate the name of the component that needs to be cached

<keep-alive>
  <router-view v-if="$route.meta.keepAlive">
    <!-- Here are the view components that will be cached, such as Home! -->
  </router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
  <!-- Here are view components that are not cached, such as Edit! -->
</router-view>

In fact, just use keep-alive to include the original components. The included components are not slots like ordinary components. keep-alive is just an abstract component. For details, please read the next article " vue keep-alive(2): Analyzing the Implementation Principle of Keep-alive - Organizing Study Notes ".

keep-alive 的props

  • include  - string or regular expression, only matching components will be cached

  • exclude  - a string or regular expression, any matching components will not be cached

  • max - The maximum number of cache components. If the upper limit is exceeded, the LRU policy will be used to replace the cached data.

keep-alive+vue component declaration cycle+routing guard

The function of keep-alive is to cache the component in memory (preventing the component from being destroyed), and keep all the states in it when it is rendered next time.

Note: What is actually saved in the memory is not the node string of the rendered HTML, but the virtualized DOM object compiled by Vue .

The purpose is to prevent repeated rendering of the DOM . When the data changes, the VM's diff update will be triggered.

The implementation of all functions of Vue is centered around its life cycle. Calling the corresponding hook functions at different stages of the life cycle can realize the two important functions of component data management and DOM rendering .

keep-alive caches components, but it also blocks Vue's normal life cycle process .

The life cycle of vue is : beforeCreate, created, beforeMonted, mounted, beforeUpdate, update, beforeDestroy, destroyed. For details, please refer to " Vue2.x pit summary - review and comparison with angularJS/React "

When switching between different pages/components, some requested data will be requested, and each request will cause repeated rendering and affect performance. This data can be stored in the cache - at this time, keep-alive is used to wrap the component, but in this case the above eight life cycle hooks will be invalid.

Instead, activated and deactivated will be triggered in all nested components in the tree in 2.2.0 and higher  .

  • activate : is a life cycle hook used when the wrapped component is activated (activated will be executed every time the component is called - including the first time).

    • Enter the cache route/component for the first time: beforeRouteEnter > beforeCreate > created > mounted > activated > ... ... > beforeRouteLeave > deactivated

    • When entering the component again: beforeRouteEnter > activated > ... ... > beforeRouteLeave > deactivated

  • deactivated : called when the wrapped component stops being used

Theoretically: When keep-alive is introduced into the project,

  • When the page is entered for the first time, the triggering sequence of the hook function is created -> mounted -> activated.

  • Deactivated is triggered when exiting.

  • When entering again (forward or backward), only activated is triggered. If the refresh page is processed in created or mounted, this hook is not called and cannot be refreshed.

beforeRouteEnter will always trigger

  • When keep-alive is not used,

    beforeRouteEnter --> created --> mounted --> destroyed

  • When using keep-alive,

    beforeRouteEnter --> created --> mounted --> activated --> deactivated

More pitfalls, recommended to read

" Comprehensive solution to the Vue life cycle (vueRouter, keep-alive, life cycle) "

" Vue Pit Climbing Journey--implementation of page caching and remembering scroll position functions using keepAlive in combination with vue-router and several points that need attention "

keep-alive activate is applied in the project

How easy is it to not just click on the details page and then return directly?

status refresh

For example, if you add it to the shopping cart on the details page, the list page needs to display the number of purchased cars, etc., which needs to be implemented in combination with vuex.

What's more, every time you enter this page, you must request some background data, which needs to be implemented in activate.

I found that a colleague's implementation is: leave the page, settimeout, guess a time to notify the list page, and perform operations. This, um, works, but it’s absolutely unreliable!

scroll bar reset

It can be solved by: vue-keep-scroll-position  component. But this component only refreshes the routing container. What if there is a list in the page that needs to be refreshed?

In pages that need to be cached, such as beforeRouteLeave on list pages, scroll bar position information is stored. Other operating principles are similar.

// When leaving
beforeRouteLeave(to: any, from: any, next: any) {
    //let  dom: HTMLElement|null = document.getElementById('list');
     let dom = this.$refs.list;
     // When leaving, find a way to store the scroll position.
     to.meta.scrollTop = dom.scrollTop;
     
}
//When returning
activated() {
  //After activation, add stored information and reset the scroll bar
  const scrollTop = this.$route.meta.scrollTop;
    if (scrollTop) {
      this.$nextTick(() => {
        this.$refs.list.scrollTop = scrollTop;
      });
    }
}

What needs to be noted here is that do not refresh the scroll bar position information in real time on the list page by listening to the scroll event - there is no necessary performance consumption.

keep-alive cache page limit

Only when rolling back from page B to page A, the previous cache transition of page A is restored. Let’s talk about a common case.

To jump from the panel page to the edit page, the panel page needs to be cached. That is: go back to the panel page from the editing page, and the panel page is still the same as before (the way it was before entering).

Panel page

export default [
  {
    path: '/panel/:biz_id',
    name: 'panel',
    component: () => import(/* webpackChunkName: "panel-page-chunk" */'@/pages/panel/index.vue'),
    children: [
      {
        path: 'list_panel/:os_id',
        name: 'listPanel',
        component: () => import(/* webpackPrefetch: true */ /* webpackChunkName: "panel-page-chunk" */'@/pages/panel/list.vue'),
        props: route => ({
          osId: route.params.os_id,
        }),
        meta: {
          keepAlive: true,
        },
      },
      {
        path: 'panel-info',
        name: 'panel-info',
        component: () => import(/* webpackPrefetch: true */ /* webpackChunkName: "panel-page-chunk" */'@/pages/panel/info.vue'),
      },
    ],
  },
  {
    path: '/panel/:biz_id/chart_editor/:os_id/:chart_id?',
    name: 'chartEditor',
    component: () => import(/* webpackPrefetch: true */ /* webpackChunkName: "panel-page-chunk" */'@/pages/panel/chartEditor.vue'),
    meta: {
      keepAlive: false,
    },
    props: route => ({
      osId: route.params.os_id,
    }),
  },
];

Need to set beforeRouteLeave in the panel page, from.meta.keepAlive = false;

On the edit page, set beforeRouteLeave, to.meta.keepAlive = true;

This is actually a general solution, such as " Understanding and Application of Keep-alive in Cache ". Personally, I think this solution is better. " Correct Usage of Keep-alive in Vue Component Cache ". In fact, it is to set the weight of the path in the meta of the route. For example, the weight of the first-level page is 100, the weight of the second-level page is 1000, and the weight of the third-level page is 1000. Make the sliding direction of page caching and page switching animation based on the weight.

Summary of things to note about keep-alive

  • First match the name field of the included component. If name is not available, match the registered name in the current component components configuration

  • Won't work properly with functional components because they don't have cached instances

  • When the matching condition exists in both include and exclude, exclude has the highest priority (current vue 2.4.2 version). For example: if inclusion and exclusion also match component A, then component A will not be cached. 

  • Contained in include, but consistent with exclude, activated and deactivated will not be called .

Reference article:

vue learning---life cycle hook activated, deactivated  https://www.cnblogs.com/mengtong/p/10966955.html

The problem and solution of the Vue page rollback mounted function not being executed  https://www.cnblogs.com/candy-xia/p/11425357.html

In-depth understanding of vue-router's keep-alive  In-depth understanding of vue-router's keep-alive_vue.js_Script Home

Official: <keep-alive> component cache issue #811 https://github.com/vuejs/vue-router/issues/811#issuecomment-353875880

Reprinted from this site's article " vue keep-alive(1): How does vue router ensure that the page does not refresh when the page is rolled back?" 》,
please indicate the source: vue keep-alive(1): How does vue router ensure that the page does not refresh when it returns? - Summary of vue entry - Zhou Junjun's personal website

Guess you like

Origin blog.csdn.net/u012244479/article/details/118370732