vue通过iframe引入一个外链地址,怎么保证每次切换回这个已经打开的tab页的时候iframe不会重新加载

我有很多的报表页。这些页面是通过外链引入的。他们只有id是不一样的。

我的页面是这样写的。router定义成

复制代码
{
  path: '/report-template/:id',
  title: '统计模版',
  name: 'report-template',
  component: () =>
      import(/*webpackChunkName: "report-template"*/ '@/views/report-management/report-template.vue'),
},

report-template.vue

复制代码
<template>
  <div class="external-page-container">
    <iframe
        :src="srcUrl"
        frameborder="0"
        width="100%"
        allowfullscreen
    ></iframe>
  </div>
</template>

<script>
export default {
  name:'report-template',
  data() {
    return {
      id: 0,
      srcUrl: "",
    }
  },
  watch: {
    '$route.params' (to) {
      // 路由发生变化.iframe地址改变
     this.$nextTick(()=>{
       this.getIframe()
     })
    },
  },
  mounted(){
    this.getIframe()
  },
  methods:{
    getIframe(){
      this.id=this.$route.params.id;
      this.srcUrl=`https://jm/jmreport/view/${this.id}`; //拼接访问地址
    }
  }
}
</script>

<style scoped>
.external-page-container{
  width: 100%;
  height: 100%;
  position: relative;
}
iframe{
  position: absolute;
  top: 0;
  bottom: 0;
  height: 100%;
}
</style>

上面能实现点击不同的报表菜单。展示不同的报表数据。

但是发现按照上面的写法打开了一个报表菜单之后再点击别的。再次切换回这个报表的菜单。页面会刷新一下,重新加载这个iframe。如何做到打开之后就记住当时的状态,包含输入框查询的内容。

这时候我们可以把iframe打开过的id都保存起来,把所有的iframe都以v-show的形式显示和隐藏。并且注意最外层的要加上keep-alive。下面cachePage包含所有打开的路由页面

复制代码
<!-- 路由渲染的右侧所有数据的地方在这 包含着缓存数据 -->
<keep-alive :include="cachePage">
  <router-view></router-view>
</keep-alive>

然后优化这个report-template.vue

复制代码
<template>
  <div class="external-page-container">
    <div
      v-for="openedId in openedReportIds"
      :key="openedId"
      class="iframe-wrapper"
      v-show="currentId == openedId"
    >
      <!-- 使用缓存的 urlMap,打开后的url再次切换回去可以记住之前的筛选内容 -->
      <iframe
        :src="urlMap[openedId]"
        frameborder="0"
        width="100%"
        height="100%"
        allowfullscreen
      ></iframe>
    </div>
  </div>
</template>

<script>
export default {
  name: 'report-template',
  data() {
    return {
      currentId: null,
      openedReportIds: [],
      urlMap: {} // 缓存每个 ID 对应的完整 URL
    }
  },
  watch: {
    '$route.params.id': {
      handler(newId) {
        if (newId && newId !== this.currentId) {
          this.currentId = newId;
          if (!this.openedReportIds.includes(newId)) {
            this.openedReportIds.push(newId);
            // 只在首次打开时计算并缓存 URL
            this.urlMap[newId] = this.getIframeUrl(newId);
          }
        }
      },
      immediate: true
    }
  },
  methods: {
    getIframeUrl(id) {
      this.id=this.$route.params.id;         this.srcUrl=`https://jm/jmreport/view/${this.id}`; //拼接访问地址
    }
  }
}
</script>
<style scoped>
.external-page-container{
  width: 100%;
  height: 100%;
  position: relative;
}
iframe{
  position: absolute;
  top: 0;
  bottom: 0;
  height: 100%;
}
</style>
相关推荐
前端摸鱼匠20 分钟前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker42 分钟前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
donecoding2 小时前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马2 小时前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren2 小时前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川2 小时前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端
Linsk2 小时前
Java和JavaScript的关系真是雷峰和雷峰塔的关系吗?
java·javascript·oracle
当时只道寻常2 小时前
浏览器文本复制到剪贴板:企业级最佳实践
javascript
jinanwuhuaguo3 小时前
(第二十九篇)OpenClaw 实时与具身的跃迁——从异步孤岛到数字世界的“原住民”
前端·网络·人工智能·重构·openclaw