iframe实现缓存

实现缓存

1、 keep-alive缓存不了iframe界面原因

(1)vue中的keep-alive
【1】原理:Vue 的缓存机制并不是直接存储 DOM 结构,而是将 DOM 节点抽象成了一个个 VNode节点。因此,Vue 的 keep-alive 缓存也是基于 VNode节点 而不是直接存储 DOM 节点。在需要渲染的时候从Vnode渲染到真实DOM上。
【2】参数:Keep-alive 组件提供了 include 和 exclude 两个属性,允许组件有条件的进行缓存。
  include: 字符串或正则表达式。只有匹配的组件会被缓存。
  exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
【3】Keep-alive 组件提供了两个生命钩子函数,分别是 activated 和 deactivated 。
  activated :当页面存在缓存的时候执行该函数。
  deactivated :在页面结束时触发该方法,可清除掉滚动方法等缓存。
(2)iframe中keep-alive机制失效原因:iframe页里的内容并不属于节点的信息,所以使用keep-alive依然会重新渲染iframe内的内容。而且iframe每一次渲染就相当于打开一个新的网页窗口,即使把节点保存下来,在渲染时iframe页还是刷新的。

2、 解决方案

判断当前页面是普通页面还是iframe页面,让普通页面走route-view,用v-if控制显隐,让iframe走动态组件(component :is),组件指向iframe文件,用v-show控制显隐,通过v-show不销毁组件的方式,来实现缓存iframe的效果

3、核心代码

layout文件


    <a-layout-content>
      <!-- 非iframe页面 -->
      <keep-alive :include="cacheViewString">
        <router-view v-if="!isIframe" :key="getRoute" style="height:100%;" />
      </keep-alive>
      <!-- iframe页面 -->
      <div v-show="isIframe">
        <component
          v-for="item in iframeList"
          :key="item"
          is="iframeComponentName"
          v-show="isIframe && $route.path.indexOf(item) > -1"
        />
      </div>
    </a-layout-content>
	// 指向iframe文件
	import iframeComponentName from '@/views/oh/OhSystemIframe.vue';
	
	@Component({
	  components: {
	    iframeComponentName
	  }
	})
	export default class Layout extends Vue {
	  iframeList:any = []; // iframe菜单集合
	  
	  @Watch('$route')
	  onRouteChange(route:any) {
	  	// 根据路由判断当前页面是否是iframe --> 判断规则视情况而定
	    this.renderIframeList(route.path)
	  }
	
	  renderIframeList(path:any) {
	    if (!path.includes('oh_iframe')) return
	    const notExit = this.iframeList.findIndex((item:any) => item === path) === -1
	    if (notExit) {
	      this.iframeList.push(path)
	    }
	  }
	
	  get isIframe() {
	    // iframe标识:当前页面是否是iframe
	    /**
	    注意:判断规则视情况而定
	    **/
	    return this.$route.path.includes('oh_iframe');
	  }
	}

OhSystemIframe文件

<template>
  <div class="peis-body__main">
    <div class="peis-body">
      <iframe
        id="ohIframe"
        :src="iframeSrc"
        frameborder="0"
      ></iframe>
    </div>
  </div>
</template>

以下ts代码为拼接iframeSrc的过程,可忽略,但有一个知识点 给iframe传参:postSession()


<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component({
  name: 'OhSystemIframe',
  components: {},
})
export default class OhSystemIframe extends Vue {
  iframeSrc: any = '';
  mounted() {
    this.renderIframeSrc();
  }

  renderIframeSrc() {
    /* 拼接iframe地址 */
    const sysFlag = '/oh/#'; // 职业病系统标识
    const query = '?systemFrom=peis'; // 增加体检系统挂载标识
    let targetUrl;
    // 本地环境
    if (window.location.href.includes('localhost')) {
      const ohHost = 'http://localhost:9528/#'; // 本地职业病项目地址 -->确保本地已启动职业病的前端项目
      targetUrl = ohHost + window.location.href.split('/#/oh_iframe')[1];
    } else {
      // 测试环境
      targetUrl = window.location.href.split('/peis/#/oh_iframe/')[0] + sysFlag + this.$route.path.split('/oh_iframe')[1];
    }
    this.iframeSrc = targetUrl + query;
    // this.postSession(); // 给职业病iframe传参 暂时用不到
  }

  postSession() {
  	// 传参方式
    const data = {
      selectedSystem: { deptCode: '72', deptId: '91', deptName: '健康管理中心', orgId: '10033', sysytemId: '100000', systemName: '职业病', url: 'oh/', userSysId: '5391553094598134274', userSysName: '职业病体检主任' },
    };
    this.$nextTick(() => {
      const iframe: any = document.getElementById('ohIframe');
      iframe.onload = () => {
        iframe.contentWindow.postMessage(JSON.stringify(data), '*');
      };
    });
  }
  // 接收参数方式
  //  window.addEventListener('message', (data: any) => {
      /* 挂载系统时 接收传入的参数 */
      // data
  //  });
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值