Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeepAlive provide function to delete cache #6038

Open
xikeqian opened this issue May 31, 2022 · 5 comments
Open

KeepAlive provide function to delete cache #6038

xikeqian opened this issue May 31, 2022 · 5 comments
Labels

Comments

@xikeqian
Copy link

What problem does this feature solve?

We can open multiple tabs. The components corresponding to the tabs use the keepalive cache. We need to destroy the keepalive cache when closing the tabs to release the cache. We also know KeepAlive max property but that can't delete specified cache. hope expose keys and cache property in production

What does the proposed API look like?

hope expose keys and cache property in production or provide function to delete cache by key

@xikeqian xikeqian added the ✨ feature request New feature or request label May 31, 2022
@lidlanca
Copy link
Contributor

lidlanca commented Jun 1, 2022

https://github.com/HcySunYang/rfcs/blob/keepalive-cache-management-and-match-rules/active-rfcs/0000-keepalive-cache-management-and-match-rules.md

#4339

@xikeqian
Copy link
Author

xikeqian commented Jun 6, 2022

Has this PR passed? @lidlanca

@lidlanca
Copy link
Contributor

lidlanca commented Jun 6, 2022

its been open for more than a year, I don't know what blocks it.

@liuzw2579
Copy link

maybe you can do it use KeepAlive.

If use router controll it, record route:

// record tabs
const pages = reactive([]);

// when route changed, record it
router.afterEach((to) => {
  const key = getKeyFromRoute(to);
  if (pages.find((tab) => tab.key === key)) {
    return;
  }
  pages.push({
    key,
    component: null,
  });
});

// calc key of the route
function getKeyFromRoute(route) {
  const keepAlive = route.meta.keepAlive ?? "path";

  return keepAlive === "path"
    ? route.path
    : keepAlive === "fullPath"
    ? route.fullPath
    : route.name;
}

then, render router view:

// render the router view
function setup() {
  // keepalive components name
  const includes = ref([]);

  // when tabs changed, calc the includes
  watch(
    () => pages,
    () => {
      // delay update, because of current component's onUnmounted callback
      requestIdleCallback(() => {
        includes.value = theme.pages
          .filter((tab) => tab.keepAlive)
          .map((tab) => `Route@${tab.key}`);
      });
    }
  );

  return () => (
    <RouterView>
      {{
        default: ({ Component, route }) => {
          if (!Component) return null;
          const key = getKeyFromRoute(route);
          // notice, use reactive var 'pages' in slots function maybe cause this slot duplicate render. 
          // should use other var to avoid it
          const tab = pages.find((tab) => key === tab.key);
          if (!tab) return null;

          // wrapper component name use key of route
          if (!tab.component) {
            tab.component = markRaw(
              defineComponent({
                name: `Route@${key}`,
                render: () => Component,
              })
            );
          }

          const RouterViewRender = tab.component;

          return (
            <KeepAlive include={includes.value}>
              <RouterViewRender />
            </KeepAlive>
          );
        },
      }}
    </RouterView>
  );
}

when close tab, delete tab from pages:

function close(tabIndex) {
  pages.slice(tabIndex, 1)
}

@xikeqian
Copy link
Author

xikeqian commented Aug 8, 2022

maybe you can do it use KeepAlive.

If use router controll it, record route:

// record tabs
const pages = reactive([]);

// when route changed, record it
router.afterEach((to) => {
  const key = getKeyFromRoute(to);
  if (pages.find((tab) => tab.key === key)) {
    return;
  }
  pages.push({
    key,
    component: null,
  });
});

// calc key of the route
function getKeyFromRoute(route) {
  const keepAlive = route.meta.keepAlive ?? "path";

  return keepAlive === "path"
    ? route.path
    : keepAlive === "fullPath"
    ? route.fullPath
    : route.name;
}

then, render router view:

// render the router view
function setup() {
  // keepalive components name
  const includes = ref([]);

  // when tabs changed, calc the includes
  watch(
    () => pages,
    () => {
      // delay update, because of current component's onUnmounted callback
      requestIdleCallback(() => {
        includes.value = theme.pages
          .filter((tab) => tab.keepAlive)
          .map((tab) => `Route@${tab.key}`);
      });
    }
  );

  return () => (
    <RouterView>
      {{
        default: ({ Component, route }) => {
          if (!Component) return null;
          const key = getKeyFromRoute(route);
          // notice, use reactive var 'pages' in slots function maybe cause this slot duplicate render. 
          // should use other var to avoid it
          const tab = pages.find((tab) => key === tab.key);
          if (!tab) return null;

          // wrapper component name use key of route
          if (!tab.component) {
            tab.component = markRaw(
              defineComponent({
                name: `Route@${key}`,
                render: () => Component,
              })
            );
          }

          const RouterViewRender = tab.component;

          return (
            <KeepAlive include={includes.value}>
              <RouterViewRender />
            </KeepAlive>
          );
        },
      }}
    </RouterView>
  );
}

when close tab, delete tab from pages:

function close(tabIndex) {
  pages.slice(tabIndex, 1)
}

This seems to work by redefine component name , let me try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants