• vue页面和 iframe多页面无刷新方案和并行存在解决方案


    面临问题 : back的后台以jsp嵌套iframe为主, 所以在前端框架要把iframe无刷新嵌套和vue页面进行并行使用,vue的keep-alive只能对虚拟dom树 vtree 进行缓存无法缓存iframe,所以要对iframe进行处理

    tab标签的切换效果具体参考若依框架的tab切换,可以去若依看源码,若依源码没有实现这个效果,以下代码基于若依源码进行优化

    一开始打算把每个iframe嵌入到router页面里面,但这样会导致几十个iframe页面全部占用内存,用v-show显示,所以要做成点击的才会占有内存

    实现效果

    1. 每个iframe页面有单独的路由
    2. 刷新页面可以对当前iframe页面进行刷新
      
    3. vue 页面未缓存和缓存和iframe页面3者进行并行存在,并且达到效果
      
    4. 刷新标签可以对iframe页面进行刷新
      
    5. 点击才会占用内存
      

    解决方案 采用iframe和keeplive分开的方案,用v-show进行判断,把每个iframe嵌入到router里的/frame/: 的动态路由里面,用户点击iiframe的菜单就会生成一个 /iframe/brand-list的页面,页面根据逻辑去找到对应iframe去生成tab,并且建立内存资源达到切换tab不刷新的效果 以下为实现效果*
    在这里插入图片描述 最终实现效果,5个页面切换 无感刷新,并且iframe动态引入

    iframe路由页面
    //iframe 路由
    const commonPath = import.meta.env.VITE_APP_PATH || 'g-back'
    
    getIframeList(){
        return[
          {
            fullPath:`${commonPath}/iframe/brand-list`,
            path:`${commonPath}/iframe/brand-list`,
            // name:"brand-list",
            meta:{
              title:"品牌维护",
              link:'baidu.com',
            }
          },
          {
            fullPath:`${commonPath}/iframe/brand-list`,
            path:`${commonPath}/iframe/category-goodsType`,
            // name:"category-goodsType",
            meta:{
              title:"品牌分类",
              link:'baidu.com',
    
            }
          },
          {
            fullPath:`${commonPath}/iframe/brand-list`,
            path:`${commonPath}/iframe/standard-list`,
            // name:"standard-list",
            meta:{
              title:"商品标准",
              link:'baidu.com',
    
            }
          }
        ]
      }
    
    
    
    
    router.js页面 vue路由
    const remainingRouter: AppRouteRecordRaw[] = [
      {
        path: `/`,
        redirect: '/g-back/index',
      },
      {
        path: '/g-back',
        redirect: '/g-back/index',
        children: [
          {
            path: '/g-back/index',
            component: () => import('@/views/home/index.vue'),
            name: 'index',
            meta: { title: '首页', icon: 'dashboard' }
          }
        ]
      },
      {
        path: '/404',
        component: () => import('@/views/404/index.vue'),
        name: '404',
        meta: { title: '404', icon: 'dashboard'}
      },
      {
        path: `${commonPath}/iframe/:id`,
        component: () => import('@/views/iframe/index.vue'),
        meta: {
          title: 'iframe',
          link:true
        }
      },
      {
        path: '/redirect',
        // hidden: true,
        children: [
          {
            path: '/redirect/:path(.*)',
            component: () => import('@/views/redirect/index.vue')
          }
        ]
      }
    ]
    以上 所有的iframe页面都存在/iframe/:id 中 ,用动态路由展示iframe的页面 
    以上 brand-list 就是品牌维护的页面路由
    App.vue页面
    <template>
      <section class="app-main">
        <router-view v-slot="{ Component, route }" :key="routes.path" v-if="!routes.meta.link">
          <transition name="fade-transform" mode="out-in">
            <keep-alive :include="tagsViewStore.cachedViews">
              <component v-if="!route.meta.link" :is="Component"  />
            </keep-alive>
          </transition>
        </router-view>
        <iframe-toggle />
      </section>
    </template>
    
    <script setup>
    import iframeToggle from "../IframeToggle/index.vue";
    import useTagsViewStore from "@/store/modules/tagsView";
    const routes = useRoute()
    watch(routes,(val)=>{
      console.log(val)
    })
    const tagsViewStore = useTagsViewStore();
    </script>
    注意一定要给router-view key值,以实现每个iframe页面的变化,router-view都会改变它的路由
    iframeToggle页面
    <template>
        <inner-link
        v-for="(item, index) in uniqBy(iframeViews,'path')"
        :key="item.path"
        :iframeId="'iframe' + index"
        v-show="route.path === item.path"
        :src="iframeUrl(item.meta.link, item.query)"
      ></inner-link>
    </template>
    
    <script setup>
    import InnerLink from "../InnerLink/index.vue";
    import useTagsViewStore from "@/store/modules/tagsView";
    import { uniqBy } from 'lodash'
    
    const route = useRoute();
    const tagsViewStore = useTagsViewStore();
    const iframeViews = computed(()=>tagsViewStore.iframeViews)
    
    // console.log(iframeViews.value)
    function iframeUrl(url, query) {
      // if (Object.keys(query).length > 0) {
      //   let params = Object.keys(query).map((key) => key + "=" + query[key]).join("&");
      //   return url + "?" + params;
      // }
      return url;
    }
    </script>
    InnerLink页面
    <template>
      <div v-loading="loading" :style="'height:' + height">
        <iframe
          :id="iframeId"
          style="width: 100%; height: 100%"
          :src="src"
          frameborder="no"
        ></iframe>
      </div>
    </template>
    
    <script setup>
    const props = defineProps({
      src: {
        type: String,
        default: "/"
      },
      iframeId: {
        type: String
      }
    });
    const loading = ref(true)
    const height = ref(document.documentElement.clientHeight - 94.5 + "px;")
    
    onMounted(() => {
      setTimeout(() => {
        loading.value = false;
      }, 300);
      window.onresize = function temp() {
        height.value = document.documentElement.clientHeight - 94.5 + "px;";
      };
    })
    </script>
    
    
    
    
  • 相关阅读:
    如何添加cookie
    企业数字化转型,应该从零开始建设数据文化
    网工内推 | 金融业,网络管理岗,CCIE优先,最高30k
    Hadoop 集群搭建
    JavaScript变量及声明
    Linux hook 技术一个简单demo分析
    Redis基本命令和常用数据类型
    Si24R2F+2.4GHz ISM 频段低功耗无线集成嵌入式发射基带无线发射芯片
    理解红黑树
    测试环境搭建整套大数据系统(十四:搭建mysql8)
  • 原文地址:https://blog.csdn.net/weixin_40461134/article/details/139658722