Project background
The project uses RuoYiFrame, but the system will embed a large screen and report page, which is implemented using an iframe.
The cache function is provided in the menu management of the framework, which is implemented using keep-alive, but it does not take effect for the iframe page. Since the large-screen page is loading slowly, when the user switches the tab page, the iframe needs to be reloaded and cannot record the previous operation content, which greatly affects the user experience.
keep-alive
The cache principle of keep-alive is actually a cached vnode. Its essence is a JS object, a string of data. For an iframe, there is only one url cached, and it is impossible to know its internal structure and data, so it cannot be cached.
Solution
Bypass routing management, implement dynamic loading of iframes in the outermost file(), and use v-show to control iframe display/hide. It is equivalent to overlaying an independent iframe page at the top of the original page through positioning.
Specific implementation
When the configuration menu, add one more configuration parameter to the page containing the iframe. isIframe:true, for front-end distinction.
Store in the store: cached iframe information {path,url} array, menu bar status (determine the width of the iframe according to the menu expansion and collapse status)
const useIframesStore = defineStore( 'iframes', { state: () => ({ cacheIframes: [], }), actions: { addIframe(iframe) { (iframe) }, delIframe(path) { = (item => !== path) }, clearCache() { = [] } } } )
- : v-for loads cached iframe information in the store. The control condition of v-show is to compare whether the path of the current route is consistent with the path of the iframe.
- Style problem: Because the iframe component is not in the router-view, it has nothing to do with the menu and needs to be set independently; in order to display the effect normally, it is suspended in the normal page position in an absolute position; width needs to display the corresponding width according to the menu status stored in the store
<template> <router-view/> <!-- iframePage --> <div v-if="!=='/login'" :class="`iframes w-menu${?'1':'0'}`" :style="`height:${iframeHeight};z-index:${?'999':'-999'}`"> <Iframe v-for="i in cacheIframes" :key="" :src="" v-show=" === " title="iframe"></Iframe> </div> </template> ... <style lang="scss" scoped> .w-menu1{ width: calc(100% - #{$base-sidebar-width}); } .w-menu0{ width: calc(100% - 54px); } </style>
- Route Guard beforeEach: When jumping the route, when the route parameter isIframe is true, it means that it will jump to the iframe page soon. Call the store method to add iframe information to the iframe array.
((to, from, next) => { const iframesStore = useIframesStore(); // Jump iframe page if(){ if((item => === ).length==0){ // Add cache ({ path: , url: }) } } next(); })
- When closing the tab sign: delete the corresponding iframe item in the store
function closeSelectedTag(view) { if(){ (); } ... }
- After the user logs out, clear the cache
... logOut() { return new Promise((resolve, reject) => { logout().then(() => { = '' = [] = [] removeToken() // Clear the cache useIframesStore().clearCache() resolve() }).catch(error => { reject(error) }) }) }
- In the OAI menu management, use the parameter isIframe control, and the corresponding component page is set to a blank page to avoid loading two iframes at the same time taking up resources.
This is the end of this article about the solution of Vue's inability to cache iframes. For more related content related to Vue iframes, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!