当前位置:网站首页>Vue cleans up the keepalive cache scheme in a timely manner

Vue cleans up the keepalive cache scheme in a timely manner

2022-07-04 20:56:00 ZTStory

demand

Single page application , The user enters the form filling page , The form content needs to be initialized , The filling process may involve operations such as map point selection or list selection , You need to go to the new page to select and recall the display .

At this time, we need to cache the form filling page instance , When you exit the form and fill in or submit the contents of the form , You need to destroy the current form instance , Re initialize next time

reflection

Speaking of Vue cache , We must first choose the caching scheme provided by the official keep-alive Built in components to achieve .

keep-alive Components provide us with the ability to cache components , You can completely save the state of the current component , This helped us a lot

But in the actual business scenario , We often cache pages on demand , It's like App Develop that , Each page is a separate page instance , because Vue Router The limitation of , Each page has a fixed path, So every time you visit this path Will hit the same component instance

At this time, some friends may say

EH , No, you can use activated To update or process the page ?

you 're right , It can be like this , however , Some operations are mounted It needs to be done inside , Some need to be put activated Update inside , The code has to deal with many operations to enter the page , It's very troublesome .

At this point, there are two directions of thinking :

  1. Clear instances of cached pages when necessary
  2. Every time push On the page , Ensure that the current page is a new instance object , and App Same page stack

The second solution can physically solve the problems in the requirements , But there are many things that need to be changed , such as Vue Router When the middle road switches , Whether to use dynamic generation path , Ensure that the current page instance is not unique , And we should also do our own page stack management , Be similar to iOS Medium UINavigationController , In order to clean up the cached page instances in the stack in time

Because the changes are big , And it requires a lot of testing , So I finally chose Scheme 1 Explore and try in the direction of .

Try

1. Manual operation keep-alive Component's cache Array

// Vue 2 keep-alive  Some source code fragments 
const { cache, keys } = this;
const key: ?string =
    vnode.key == null
        ? // same constructor may get registered as different local components
          // so cid alone is not enough (#3269)
          componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : "")
        : vnode.key;
if (cache[key]) {
    vnode.componentInstance = cache[key].componentInstance;
    // make current key freshest
    remove(keys, key);
    keys.push(key);
} else {
    // delay setting the cache until update
    this.vnodeToCache = vnode;
    this.keyToCache = key;
}

adopt Route guard Delete under certain circumstances cache Page instances in the array , meanwhile destory The current instance

removeKeepAliveCacheForVueInstance(vueInstance) {
    let key =
        vueInstance.$vnode.key ??
        vueInstance.$vnode.componentOptions.Ctor.cid + (vueInstance.$vnode.componentOptions.tag ? `::${vueInstance.$vnode.componentOptions.tag}` : "");
    let cache = vueInstance.$vnode.parent.componentInstance.cache;
    let keys = vueInstance.$vnode.parent.componentInstance.keys;
    if (cache[key]) {
        vueInstance.$destroy();
        delete cache[key];
        let index = keys.indexOf(key);
        if (index > -1) {
            keys.splice(index, 1);
        }
    }
}

This scheme is cumbersome , But because it is a direct operation cache Array , There may be some unexpected leakage problems or operation problems , Although I didn't find it when I tried it myself ..

stay Vue 3 I also try to find the corresponding cache Array , I found it , however Vue 3 Source code for cache The operation permission of array is limited to the development environment

// Vue 3 KeepAlive  Component fragment 
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
    ;(instance as any).__v_cache = cache
}

After deploying the production environment, you can't pass instance.__v_cache To get cache Array , So this plan to Vue 3 There is no way to proceed .

So , There is a second attempt

2. exclude Dafa is good

Before contact with keep-alive All attention is focused on include This attribute is above , Actually exclude Attributes are equally important , And the effect is the same as our direct deletion cache Arrays are similar .

// Vue 3 KeepAlive  Component fragment 
 if (
    (include && (!name || !matches(include, name))) ||
    (exclude && name && matches(exclude, name))
    ) {
        current = vnode
        return rawVNode
    }

If exclude It's worth it , Then return the current new instance instead of cache Get in there . and exclude Priority is higher than include Of .

Take advantage of this , We can do this by manipulating exclude The content in , To achieve the effect of controlling the cached page .

and exclude stay Vue 3 The control in is more convenient , Just define a global exclude Reactive variables can be operated anywhere , The specific way of clearing depends on the business process

export const excludes = ref<string[]>([]);
//  When it needs to be deleted 
export function removeKeepAliveCache(name: string) {
    excludes.value.push(name);
}
//  When the cache needs to be restored 
export function resetKeepAliveCache(name: string) {
    excludes.value = excludes.value.filter((item) => item !== name);
}

Demo

Here's a little demo Demonstrate the cache clearing effect :

ztstory.github.io/vue-composi…

technological process :

  • Index And Input Cache pages for

  • Input Back to Index Clear when Input cache , Re enter Input Page activation cache

Demo Source code address :github.com/ZTStory/vue…

原网站

版权声明
本文为[ZTStory]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/185/202207041912277421.html