【Vue】页面使用了KeepAlive缓存机制后,切换标签含有iframe标签的界面只有最后被打开的页面有iframe正常展示

497 阅读2分钟
  • 背景交代

    • 框架: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 内挂载iframe

      1)页面初始化时将iframe的挂载信息缓存起来

      2)每次重新进到页面的时候,都会执行钩子activated,在这里将缓存的挂载信息重新挂载到iframe中

    • 方案二:切换含iframe页的界面时利用 v-show 来控制显隐(我没试!需要的自行尝试,

      使iframe的节点不被删除,以此来防止界面节点被重新更新,从而达到保存iframe节点数据的效果。

      操作步骤请可参考:vue中使用keep- alive缓存机制,切换标签含有iframe标签的界面会被重新刷新的问题处理 - CSDN

    【拓展】

    • 方案二的缺陷:
      • 由于切换标签,含iframe的component组件不会再触发路由钩子函数和生命周期函数,导致界面数据无法做更新操作,同时浏览器刷新时,界面数据会有丢失的问题
      • 我们系统含iframe的component组件虽然只有两个,但是这两组件是可以被无限打开的。所以我担心会有性能问题

参考