当前位置: 首页 > news >正文

keep-alive缓存不了iframe

最近做了个项目,其中有个页面是由 iframe 嵌套了一个另外的页面,在运行的过程中发现 KeepAlive 并不生效,每次切换路由都会触发 iframe 页面的重新渲染,代码如下:

  <router-view v-slot="{ Component }"><keep-alive :include="keepAliveList"><component :is="Component"></component></keep-alive></router-view>

看起来并没有什么问题,并且其他非 iframe 实现的页面都是可以被缓存的,因此可以推断问题出在 iframe 的实现上。

我们先了解下 KeepAlive

KeepAlive (熟悉的可跳过本节)

被 KeepAlive 包裹的组件不是真的卸载,而是从原来的容器搬运到另外一个隐藏容器中,实现“假卸载”, 当被搬运的容器需要再次挂载时,应该把组件从隐藏容器再搬运到原容器,这个过程对应到组件的生命周期就是 activated 和 deactivated

keepAlive 是需要渲染器支持的,在执行 mountComponent 时,如果发现是 __isKeepAlive 组件,那么会在上下文注入 move 方法。

function mountComponent(vnode, container, anchor) {/**... */const instance = {/** ... */state,props: shallowReactive(props),// KeepAlive 实例独有keepAliveCtx: null};const isKeepAlive = vnode.__isKeepAlive;if (isKeepAlive) {instance.keepAliveCtx = {move(vnode, container, anchor) {insert(vnode.component.subTree.el, container, anchor);},createElement};}
}

原因

通过上面的了解,我们知道,KeepAlive 缓存的是 vnode 节点,vnode 上面会有对应的真实DOM。组件“销毁”时,会将真实 DOM 移动到“隐藏容器”中,组件重新“渲染”时会从 vnode 上取到真实 DOM,再重新插入到页面中。这样对普通元素是没有影响的,但是 iframe 很特别,当其插入到页面时会重新加载,这是浏览器特性,与 Vue 无关。

解决方案

思路:路由第一次加载时将 iframe 渲染到页面中,路由切换时通过 v-show 改变显/隐。

  1. 在路由注册时,将 component 赋值为一个空组件
      {path: "/chathub",name: "chathub",component: { render() {} }, // 这里写 null 时控制台会出 warning,提示缺少 render 函数},
    
  2. 在 router-view 处,渲染 iframe,通过 v-show 来控制显示隐藏
      <ChatHub v-if="chatHubVisited" v-show="isChatHubPage"></ChatHub><router-view v-slot="{ Component }"><keep-alive :include="keepAliveList"><component :is="Component"></component></keep-alive></router-view>
    
  3. 监听路由的变化,改变 iframe 的显/隐
    const isChatHubPage = ref(false)
    // 这里是个优化,想的是只有页面访问过该路由才渲染,没访问过就不渲染该组件
    const chatHubVisited = ref(false) watch(() => routes.path,(value) => {if (value === '/chathub') {chatHubVisited.value = trueisChatHubPage.value = true} else {isChatHubPage.value = false}},{immediate: true}
    )
    
  4. ChatHub.vue组件代码(有单个或者多个iframe情况)
    <template><div class="iframe-container"><iframev-for="(item, index) in iframeList"v-show="showIframe(item, index)":key="item.url":src="item.url"frameborder="0"></iframe></div>
    </template>
    <script lang="ts" setup>
    export default {name: "ChatHub",
    };
    import { ref, reactive } from "vue";
    import { useRoute, useRouter } from "vue-router";
    const route = useRoute();const iframeList = reactive([{name: 1, url: "https://xxx"},{name: 2, url: "https://yyy"}
    ])// 是否显示
    const showIframe = (item, index) => {if (route.query.url === item.url) {return true;} else {return false;}
    };</script>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 计算机网络408考研 2022
  • C++ | Leetcode C++题解之第401题二进制手表
  • ‘“node“‘ �����ڲ����ⲿ���Ҳ���ǿ����еij��� ���������ļ���
  • CSS基本布局理解(测试)——WEB开发系列38
  • 基于Qt的串口调试工具
  • 静态和动态类型语言
  • Django笔记一:搭建Django环境与URL路径访问
  • mysql组合键唯一
  • Unreal游戏初始化流程
  • 将 Parallels Desktop(PD虚拟机)安装在移动硬盘上,有影响吗?
  • Fortran:program 和 subroutine 的区别
  • 综合型医院适合什么样的数据摆渡方式,才能服务与安全兼顾?
  • 如何通过深度学习实践来理解深度学习的核心概念
  • STM32 之 SDRAM 详解
  • 【编程基础知识】数据库表设计三范式
  • 分享一款快速APP功能测试工具
  • [iOS]Core Data浅析一 -- 启用Core Data
  • Apache的基本使用
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • CODING 缺陷管理功能正式开始公测
  • Hibernate最全面试题
  • iOS编译提示和导航提示
  • JavaScript 基本功--面试宝典
  • Java程序员幽默爆笑锦集
  • Java多态
  • Lucene解析 - 基本概念
  • MySQL的数据类型
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • 对象管理器(defineProperty)学习笔记
  • 面试总结JavaScript篇
  • 目录与文件属性:编写ls
  • 使用 @font-face
  • 找一份好的前端工作,起点很重要
  • 【干货分享】dos命令大全
  • hi-nginx-1.3.4编译安装
  • PostgreSQL之连接数修改
  • Prometheus VS InfluxDB
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​如何在iOS手机上查看应用日志
  • # 透过事物看本质的能力怎么培养?
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (4)(4.6) Triducer
  • (4.10~4.16)
  • (42)STM32——LCD显示屏实验笔记
  • (C语言)逆序输出字符串
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (规划)24届春招和25届暑假实习路线准备规划
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (三)Honghu Cloud云架构一定时调度平台
  • (一)认识微服务
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)关于如何学好游戏3D引擎编程的一些经验