vue中使用keep-alive包裹的路由页面,切换时iframe标签会重新刷新加载的处理方案
keepAlive的缓存原理:
vue 的缓存机制并不是直接存储 DOM 结构,而是将 DOM 节点抽象成了一个个 VNode节点。因此,Vue 的 keep-alive 缓存也是基于VNode节点而不是直接存储DOM 节点。在需要渲染的时候从Vnode整合渲染到真实DOM上,因此我们使用了keepAlive的页面看起来是无痛刷新的。
iframe中keep-alive机制失效原因:
iframe页里的内容并不属于节点的信息,因为它是引用了路径上的整个html,不属于自身组件的节点信息。所以使用keep-alive切换时,整个iframe都会被干掉,因此我们重新进来时会重新渲染iframe内的内容。而且iframe每一次渲染就相当于打开一个新的网页窗口,即使把节点保存下来,在渲染时iframe页还是刷新的。
如果我们去处理keepAlive的缓存机制的话,可能想想都头疼吧,毕竟牵一发而动全身。那我们换个思路,我们可以对iframe动手动脚。因为我们知道切换的时候iframe会被干掉,那么我们如果挽留它,给它重新换个家即不放在路由切换的节点上,而是同等级节点等,那么我们切换路由页面是与它无关的。当我们重新进入使用它的页面时,把它重新追回来即添加回当前页面,那不就可以保持iframe的状态了么。
<template>
<div class="iframe">
<iframe :src="iframeSrc" frameborder="0" width="100%" height="100%" v-show="isShow" ref="ifmameRef"
id="iframes">
</iframe>
</div>
</template>
<script>
export default {
data() {
return {
iframeSrc: 'xxx',
isShow: true,
dom: ''
}
},
activated() {
// 第一次激活时,选择插入到app-main这个节点,该节点包裹keepAlive整个节点,因此不会参与节点变动
// 如果不是第一次,则使用isShow来控制节点的展示
// 该方法需要和position:relative/absolute进行搭配使用,因为该iframe已经不在该组件节点里,而在外面,需要通过样式调整
if (this.dom) {
this.isShow = true
} else {
document.getElementsByClassName('app-main')[0].appendChild(this.$refs.ifmameRef)
}
},
deactivated() {
// 切换退出时,使用变量赋值该iframe节点信息,并关闭iframe展示
this.dom = this.$refs.ifmameRef
this.isShow = false
}
}
</script>
<style lang="scss" scoped>
.iframe {
height: calc(100vh - 207px);
}
// 此处就是样式变动区,根据项目位置来改变即可
#iframes {
position: absolute;
top: 30px;
left: 30px;
width: calc(96%);
height: 730px;
}
</style>