-
背景交代
- 框架:Vue2
- 页面使用了KeepAlive缓存机制
- 多页面中嵌入了iframe标签预览文件
-
问题描述
系统页面需要引入 iframe 来预览文件,自测的时候发现只有最后一次打开的页面可以正常预览文件,前面打开的页面都无法正常预览文件。
-
问题排查
- 检查页面元素,发现无法正常预览文件的页面中,整个iframe元素都没了,感觉就像是在离开这个页面的时候,iframe就被卸载了
- 一开始怀疑 JSSDK-预览文件 的SDK的机制有BUG,然后找他们一起排查,但是问题始终得不到解决
- 后来无意了解到 KeepAlive是无法缓存iframe界面
-
原因分析
-
Vue中的KeepAlive缓存机制,并不是直接存储DOM结构,而是将DOM节点抽象成一个个VNode节点。因此,Vue 的KeepAlive缓存是基于VNode节点,而不是直接存储DOM节点。在需要渲染的时候从VNode渲染到真实DOM
KeepAlive相关知识可看文章:【Vue】【内置组件】KeepAlive
-
iframe 中 KeepAlive机制失效的原因:iframe 里的内容并不属于节点的信息,所以使用KeepAlive依然会重新渲染iframe内存的内容。而iframe每一次渲染就相当于打开一个新的网页窗口,及时把节点保存下来,在渲染时iframe页还是刷新的
-
-
解决方案:
-
方案一:在组件生命周期
activated
内挂载iframe1)页面初始化时将iframe的挂载信息缓存起来
2)每次重新进到页面的时候,都会执行钩子
activated
,在这里将缓存的挂载信息重新挂载到iframe中 -
方案二:切换含iframe页的界面时利用
v-show
来控制显隐(我没试!需要的自行尝试,使iframe的节点不被删除,以此来防止界面节点被重新更新,从而达到保存iframe节点数据的效果。
操作步骤请可参考:vue中使用keep- alive缓存机制,切换标签含有iframe标签的界面会被重新刷新的问题处理 - CSDN)
【拓展】
- 方案二的缺陷:
- 由于切换标签,含iframe的component组件不会再触发路由钩子函数和生命周期函数,导致界面数据无法做更新操作,同时浏览器刷新时,界面数据会有丢失的问题
- 我们系统含iframe的component组件虽然只有两个,但是这两组件是可以被无限打开的。所以我担心会有性能问题
-