在vue中实现iframe的keepalive(不刷新)
时间:2023-04-02 19:39:19
HTML
前言最近一个需求是在vue项目中添加一个包含iframe的页面,同时在路由过程中要求不刷新iframe的内容切换过程。一开始用的是vue自带的keep-alive,发现没什么用,于是自己研究解决方案。.....Vue的keep-alive原理是保持iframe页面的状态。下面我们来弄清楚为什么Vue的keep-alive不起作用。keep-alive的原理是将组件中的节点信息保存在VNode中(内存中),需要渲染时从Vnode渲染到真实的DOM中。iframe页面中的内容不属于节点信息,所以使用keep-alive还是会重新渲染iframe中的内容。另外,我也尝试过一个想法:如果把整个iframe节点都保存起来,然后在切换的时候渲染到目标节点,难道iframe页面不刷新吗?————也是不可行的。iframe的每一次渲染都相当于打开一个新的网页窗口。即使保存了节点,iframe页面在渲染的时候还是会刷新。实现的思路由于iframe页面中的状态很难维护,这时候我想到了另外一个方法。你能玩转Vue的路由视图节点吗?在切换非iframe页面时使用vue路由,在切换iframe页面时使用v-show切换显示和隐藏,使iframe节点不会一直被删除,从而保持iframe的状态。我们简单实现一下上面的效果,代码如下:{template:'
Index
'}constroutes=[//带有iframe的两个页面{path:'/f1',name:'f1'},//带有iframe的两个页面{path:'/f2',name:'f2'},{path:'/index',component:Index}]constrouter=newVueRouter({routes});看。使用(VueRouter);newVue({render:h=>h(App),router}).$mount('#app')根组件:
转到F1转到F2GotoIndex 以上代码很简单,重点是main.js在初始化路由的时候,iframe页面没有填写属性组件,这样页面是空白的,然后在router-view节点旁边渲染iframe页面组件,以及$route.path用于判断当前路由的方向,控制iframe页面的显示和隐藏。优化上面的代码简单的解决了问题,但是还是有一些可以优化的地方:iframe页面在根节点App的时候已经渲染好了。渲染,渲染完成后,使用v-show切换显示和隐藏。每增加一个iframe页面,都要增加一段组件引入注册和调用代码。比较麻烦。我们的目标应该是为每个额外的iframe页面添加尽可能少的代码。这里的思路是:在路由配置中定义一个属性来标识页面是否包含iframe页面。根据识别,iframe页面组件是自动动态注册和渲染的,不需要手动编写额外的代码。Router-view和iframe的切换逻辑被封装到New组件中,用它来替换原来的router-view。我们先修改路由器的配置,添加一个属性名iframeComponent,用来标识是否包含iframe。该属性的值是组件文件引用main.js:importF1from'./components/f1';importF2from'./components/f2';constroutes=[{path:'/f1',name:'f1',iframeComponent:F1//用于标识是否包含iframe页面},{path:'/f2',name:'f2',iframeComponent:F2//用于识别是否包含iframe页面},{path:'/index',component:{template:'
Index
'}}]constrouter=newVueRouter({routes//(缩写)等同于routes:routes});newVue({render:h=>h(App),router}).$mount('#app')我们把第二步和第三步结合起来封装新组件iframe-router-view.vue:
该组件主要作用是生成只包含iframe页面Array对象的路由在手表上监听$route,如果判断当前页面在iframe页面列表中,则设置hasOpen属性为true,渲染组件v-show="$route.path===item.path"在显示和隐藏iframe页面之间切换。逻辑并不复杂,这里就不赘述了。结语如果大家有更好的实现方法,或者上面有什么错误需要更正,欢迎交流。以上demo的代码放在我个人的githubhttps://github.com/jmx164491960/vue-iframe-demo