Vue無(wú)法對(duì)iframe進(jìn)行緩存的解決方案
項(xiàng)目背景
項(xiàng)目采用的若依框架,但系統(tǒng)中會(huì)嵌入大屏、報(bào)表頁(yè)面,是使用iframe來實(shí)現(xiàn)的。
若依框架的菜單管理中提供了緩存功能,是使用keep-alive實(shí)現(xiàn)的,但對(duì)于iframe頁(yè)面并不生效,由于大屏頁(yè)面加載本來就較慢,當(dāng)用戶切換tab頁(yè)時(shí),iframe要重載并且無(wú)法記錄之前的操作內(nèi)容,這非常影響用戶體驗(yàn)。
keep-alive
keep-alive的緩存原理,其實(shí)是緩存的vnode,它的本質(zhì)就是js對(duì)象,是一串?dāng)?shù)據(jù),而對(duì)于iframe,緩存到的只有一個(gè)url,無(wú)法知悉其內(nèi)部的結(jié)構(gòu)與數(shù)據(jù),因此無(wú)法進(jìn)行緩存。
解決思路
繞開路由管理,在最外層文件(App.vue)中實(shí)現(xiàn)iframe動(dòng)態(tài)加載,并搭配v-show控制iframe顯示/隱藏。相當(dāng)于通過定位,將一個(gè)獨(dú)立的iframe頁(yè)面覆蓋在原有頁(yè)面的最上方,
具體實(shí)現(xiàn)
配置菜單時(shí),將含有iframe的頁(yè)面多加一個(gè)配置參數(shù) isIframe:true,用于前端區(qū)分
store中存儲(chǔ):緩存的iframe信息{path,url}數(shù)組,菜單欄狀態(tài)(根據(jù)菜單展開折疊狀態(tài)來確定iframe的寬度)
const useIframesStore = defineStore( 'iframes', { state: () => ({ cacheIframes: [], }), actions: { addIframe(iframe) { this.cacheIframes.push(iframe) }, delIframe(path) { this.cacheIframes = this.cacheIframes.filter(item => item.path !== path) }, clearCache() { this.cacheIframes = [] } } } )
- App.vue:v-for加載store中的已緩存的iframe信息,v-show的控制條件為比對(duì)當(dāng)前路由的path于iframe的path是否一致。
- 樣式問題:因?yàn)閕frame組件不在router-view內(nèi),那么它和菜單是毫無(wú)關(guān)聯(lián)的,需要獨(dú)立設(shè)置其樣式;為了正常顯示效果,采用絕對(duì)定位的方式將它懸浮在正常頁(yè)面的位置;width需要根據(jù)store中存儲(chǔ)的菜單狀態(tài)去顯示對(duì)應(yīng)的寬度
<template> <router-view/> <!-- iframe頁(yè) --> <div v-if="route.path!=='/login'" :class="`iframes w-menu${sidebar.opened?'1':'0'}`" :style="`height:${iframeHeight};z-index:${route.query.isIframe?'999':'-999'}`"> <Iframe v-for="i in cacheIframes" :key="i.path" :src="i.url" v-show="route.path === i.path" title="iframe"></Iframe> </div> </template> ... <style lang="scss" scoped> .w-menu1{ width: calc(100% - #{$base-sidebar-width}); } .w-menu0{ width: calc(100% - 54px); } </style>
- 路由守衛(wèi)beforeEach:跳轉(zhuǎn)路由時(shí),根據(jù)路由參數(shù)isIframe為true時(shí),表示即將跳轉(zhuǎn)到iframe頁(yè)面,調(diào)用store的方法往iframe數(shù)組中添加iframe信息
router.beforeEach((to, from, next) => { const iframesStore = useIframesStore(); // 跳轉(zhuǎn)iframe頁(yè) if(to.query.isIframe){ if(iframesStore.cacheIframes.filter(item => item.path === to.path).length==0){ // 添加緩存 iframesStore.addIframe({ path: to.path, url: to.query.iframeUrl }) } } next(); })
- 關(guān)閉tab簽時(shí):刪除store中對(duì)應(yīng)的iframe項(xiàng)
function closeSelectedTag(view) { if(view.query.isIframe){ iframesStore.delIframe(view.path); } ... }
- 用戶退出登錄后,清空緩存
... logOut() { return new Promise((resolve, reject) => { logout(this.token).then(() => { this.token = '' this.roles = [] this.permissions = [] removeToken() // 清空緩存 useIframesStore().clearCache() resolve() }).catch(error => { reject(error) }) }) }
- 在若依菜單管理中將iframe頁(yè)面,使用參數(shù)isIframe控制,而對(duì)應(yīng)的組件頁(yè)面設(shè)置為一個(gè)空白頁(yè),以避免同時(shí)加載兩個(gè)iframe占用資源。
到此這篇關(guān)于Vue無(wú)法對(duì)iframe進(jìn)行緩存的解決方案的文章就介紹到這了,更多相關(guān)Vue iframe無(wú)法緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于vue實(shí)現(xiàn)分頁(yè)/翻頁(yè)組件paginator示例
本篇文章主要介紹了基于vue實(shí)現(xiàn)分頁(yè)/翻頁(yè)組件paginator示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03關(guān)于vue 結(jié)合原生js 解決echarts resize問題
這篇文章主要介紹了關(guān)于vue 結(jié)合原生js 解決echarts resize問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07基于Vue3實(shí)現(xiàn)SSR(服務(wù)端渲染)功能
在現(xiàn)代網(wǎng)頁(yè)開發(fā)中,用戶體驗(yàn)日益成為網(wǎng)站成功的重要因素,從加載時(shí)間到SEO優(yōu)化,越來越多的開發(fā)者開始關(guān)注使用服務(wù)端渲染(SSR)來提升應(yīng)用的表現(xiàn),本文將深入探討 Vue 3 的 SSR 特性,并以示例代碼展示如何實(shí)現(xiàn)這一功能,需要的朋友可以參考下2024-11-11