赞
踩
参考:
Vue中对iframe实现keep alive(无刷新) - 掘金
首先,将addRoutes.js中的ifame页面的路由component改成iframeComponent。
然后,再改Home.vue,在此文件中之前就是使用keep-alive写的,在下面加个ifame的。
以下是Home.vue原来的样子(根据打开的标签页缓存)(省略了很多内容)
<template> <div> <keep-alive :include="tagsList"> <router-view></router-view> </keep-alive> </div> </template> <script> export default { data() { return { tagsList: [], } }, created() { // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 bus.$on('tags', msg => { let arr = []; for (let i = 0, len = msg.length; i < len; i++) { if (msg[i].name != 'projectFlow') { msg[i].name && arr.push(msg[i].name); } } this.tagsList = arr; }) bus.$on('removeKeep', msg => { for (let i = 0, len = this.tagsList.length; i < len; i++) { if (this.tagsList[i] == msg) { this.tagsList.splice(i, 1) break; } } }) }, mounted() { }, methods: {} } </script>
加入ifame页面缓存(实现打开的tag标签页,再次通过点击上面的tag打开不刷新页面)代码之后:
<template> <div> <keep-alive :include="tagsList"> <router-view></router-view> </keep-alive> //-----iframe页面------- <component v-for="item in hasOpenComponentsArr" :key="item.name" :is="item.name" v-show="$route.path === item.path" ></component> </div> </template> <script> export default { created() { // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 bus.$on('tags', msg => { let arr = []; for (let i = 0, len = msg.length; i < len; i++) { if (msg[i].name != 'projectFlow') { msg[i].name && arr.push(msg[i].name); } } this.tagsList = arr; }) bus.$on('removeKeep', msg => { for (let i = 0, len = this.tagsList.length; i < len; i++) { if (this.tagsList[i] == msg) { this.tagsList.splice(i, 1) break; } } }) // 设置iframe页的数组对象 const componentsArr = this.getComponentsArr(); componentsArr.forEach((item) => { Vue.component(item.name, item.component); }); this.componentsArr = componentsArr; // 判断当前路由是否iframe页 this.isOpenIframePage(); }, data() { return { componentsArr: [] // 含有iframe的页面 } }, watch: { $route() { // 判断当前路由是否iframe页 this.isOpenIframePage(); } }, computed: { // 实现懒加载,只渲染已经打开过(hasOpen:true)的iframe页 hasOpenComponentsArr() { return this.componentsArr.filter(item => item.hasOpen); } }, methods: { // 根据当前路由设置hasOpen isOpenIframePage() { const target = this.componentsArr.find(item => { return item.path === this.$route.path }); if (target && !target.hasOpen) { target.hasOpen = true; } }, // 遍历路由的所有页面,把含有iframeComponent标识的收集起来 getComponentsArr() { const router = this.$router; const routes = router.options.routes; const homeroutes = routes[routes.length-1]; const addroutes = homeroutes[0].children; const iframeArr = routes.filter(item => item.iframeComponent); return iframeArr.map((item) => { const name = item.name || item.path.replace('/', ''); return { name: name, path: item.path, hasOpen: false, // 是否打开过,默认false component: item.iframeComponent // 组件文件的引用 }; }); } } } </script>
如上代码this.$router获取不到addroutes中的路由需要手动添加,参考文章如下:
关于vue-router动态添加路由$router.options不更新的解决办法_快乐远航1的博客-CSDN博客_router.options
在addroutes.js中添加router.options.routes.push(rootRoute)手动更新$router
源代码如下:
var rootRoute = [{ path: '/', component: resolve => require(['@/components/common/Home.vue'], resolve), meta: { title: '自述文件' }, children: routeList //routeList是addroutes中所有的路由 }]; //添加新窗口打开的页面 if (routeHideList && routeHideList.length > 0) { rootRoute = rootRoute.concat(routeHideList); } //保存路由参数到store中 state.routeParam = routeParam; state.rootRoute = rootRoute; //手动更新$router router.options.routes.push(rootRoute) //动态添加路由 router.addRoutes(rootRoute)
缓存所有页面(keep-alive用法):
在 Home.vue 里面
<template>
<div id="app">
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。