What is thekeep-alive

Sometimes we don’t want components to be re-rendered to affect the experience; Or for performance reasons, avoid repeated rendering that degrades performance. Instead, you want the component to be cached and maintain its current state. This is where the keep-alive component is needed. Official website interpretation:

<keep-alive> when wrapping dynamic components, inactive component instances are cached rather than destroyed. Like <transition>, <keep-alive> is an abstract component: it does not render a DOM element on its own, nor does it appear in the parent component chain. When a component is switched within <keep-alive>, its activated and deactivated lifecycle hook functions are executed accordingly. In 2.2.0 and later, activated and deactivated will trigger in all nested components within the <keep-alive> tree. Primarily used to preserve component state or avoid re-rendering.Copy the code

Application scenarios

If the keep-alive component is not used, the page will still be re-rendered when the page is rolled back, triggering the Created hook, which is a bad experience. Using the Keep-Alive component can significantly improve the user experience in the following scenarios:

  1. Product list page Click the product to jump to the details of the product, the original information will still be displayed after the return
  2. Order list jumps to order details, returns, and so on.

keep-aliveLife cycle of

  • First entry:
    1. created > mounted > activated
    2. Trigger after exitdeactivated
  • Enter again:
    1. Only triggersactivated
  • The event mount method, etc., is only performed once in placemounted; The method that the component executes each time it goes in is placedactivated

For use in projects

Change app.vue

<div id="app" class='wrapper'> <keep-alive> <! --> <router-view v-if="$route.meta.keepAlive"> </router-view> </keep-alive> <! -- View components that don't need caching --> <router-view v-if=! ""$route.meta.keepAlive">
  </router-view>
</div>
Copy the code

2. Set keepAlive in the route

{
  path: 'list',
  name: 'itemList'// Component (resolve) {require(['@/pages/item/list'], resolve)
  },
  meta: {
    keepAlive: true,
    title: 'Merchandise Management'}}Copy the code

Three, changes,beforeEachhook

This step is to clear the useless page cache. Suppose the cache is now enabled on both pages A and B:

  • If you log in to page A for the first time and exit, the page will not be refreshed when you enter the page again. This does not fit with current business logic. What we want is for page A to advance and return, not exit and re-enter and remain the same.
  • After entering page A, I entered page B. After testing, I found that page B would display the cache of page A even though the URL had been changed

To solve this problem, determine whether the page is moving forward or backward. Add code to beforeEach hook:

let toDepth = to.path.split('/').length
let fromDepth = from.path.split('/').length
if (toDepth < fromDepth) {
  // console.log('Back off... ')
  from.meta.keepAlive = false
  to.meta.keepAlive = true
}
Copy the code

Record the scrolling position of the page

Keep-alive does not record the scrolling position of the page, so we need to record the current scrolling position during the jump and reset it to the original position when the Activated hook is triggered. Specific design ideas:

  1. indeactivatedThe hook records the current scroll position, which I’m using herelocalStorage:
 deactivated () {
   window.localStorage.setItem(this.key, JSON.stringify({
    listScrollTop: this.scrollTop
  }))
 }
Copy the code
  1. inactivatedTo roll in a hook:
this.cacheData = window.localStorage.getItem(this.key) ? JSON.parse(window.localStorage.getItem(this.key)) : null
$('.sidebar-item').scrollTop(this.cacheData.listScrollTop)
Copy the code

Reference links:

  • Vue refreshes forward and refreshes backward
  • Use keep-alive on dynamic components