Vue無法對iframe進(jìn)行緩存的解決方案
項(xiàng)目背景
項(xiàng)目采用的若依框架,但系統(tǒng)中會嵌入大屏、報表頁面,是使用iframe來實(shí)現(xiàn)的。
若依框架的菜單管理中提供了緩存功能,是使用keep-alive實(shí)現(xiàn)的,但對于iframe頁面并不生效,由于大屏頁面加載本來就較慢,當(dāng)用戶切換tab頁時,iframe要重載并且無法記錄之前的操作內(nèi)容,這非常影響用戶體驗(yàn)。
keep-alive
keep-alive的緩存原理,其實(shí)是緩存的vnode,它的本質(zhì)就是js對象,是一串?dāng)?shù)據(jù),而對于iframe,緩存到的只有一個url,無法知悉其內(nèi)部的結(jié)構(gòu)與數(shù)據(jù),因此無法進(jìn)行緩存。
解決思路
繞開路由管理,在最外層文件(App.vue)中實(shí)現(xiàn)iframe動態(tài)加載,并搭配v-show控制iframe顯示/隱藏。相當(dāng)于通過定位,將一個獨(dú)立的iframe頁面覆蓋在原有頁面的最上方,
具體實(shí)現(xiàn)
配置菜單時,將含有iframe的頁面多加一個配置參數(shù) isIframe:true,用于前端區(qū)分
store中存儲:緩存的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的控制條件為比對當(dāng)前路由的path于iframe的path是否一致。
- 樣式問題:因?yàn)閕frame組件不在router-view內(nèi),那么它和菜單是毫無關(guān)聯(lián)的,需要獨(dú)立設(shè)置其樣式;為了正常顯示效果,采用絕對定位的方式將它懸浮在正常頁面的位置;width需要根據(jù)store中存儲的菜單狀態(tài)去顯示對應(yīng)的寬度
<template>
<router-view/>
<!-- iframe頁 -->
<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)路由時,根據(jù)路由參數(shù)isIframe為true時,表示即將跳轉(zhuǎn)到iframe頁面,調(diào)用store的方法往iframe數(shù)組中添加iframe信息
router.beforeEach((to, from, next) => {
const iframesStore = useIframesStore();
// 跳轉(zhuǎn)iframe頁
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簽時:刪除store中對應(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頁面,使用參數(shù)isIframe控制,而對應(yīng)的組件頁面設(shè)置為一個空白頁,以避免同時加載兩個iframe占用資源。
到此這篇關(guān)于Vue無法對iframe進(jìn)行緩存的解決方案的文章就介紹到這了,更多相關(guān)Vue iframe無法緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于vue實(shí)現(xiàn)分頁/翻頁組件paginator示例
本篇文章主要介紹了基于vue實(shí)現(xiàn)分頁/翻頁組件paginator示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
關(guān)于vue 結(jié)合原生js 解決echarts resize問題
這篇文章主要介紹了關(guān)于vue 結(jié)合原生js 解決echarts resize問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
基于Vue3實(shí)現(xiàn)SSR(服務(wù)端渲染)功能
在現(xiàn)代網(wǎng)頁開發(fā)中,用戶體驗(yàn)日益成為網(wǎng)站成功的重要因素,從加載時間到SEO優(yōu)化,越來越多的開發(fā)者開始關(guān)注使用服務(wù)端渲染(SSR)來提升應(yīng)用的表現(xiàn),本文將深入探討 Vue 3 的 SSR 特性,并以示例代碼展示如何實(shí)現(xiàn)這一功能,需要的朋友可以參考下2024-11-11

