Browse Source

优化页面内嵌iframe切换tab不刷新数据

RuoYi 2 years ago
parent
commit
439b134c9b

+ 5 - 0
src/assets/styles/transition.scss

@@ -12,11 +12,16 @@
 }
 
 /* fade-transform */
+.fade-transform--move,
 .fade-transform-leave-active,
 .fade-transform-enter-active {
   transition: all .5s;
 }
 
+.fade-transform-leave-active {
+  position: absolute;
+}
+
 .fade-transform-enter {
   opacity: 0;
   transform: translateX(-30px);

+ 4 - 7
src/layout/components/AppMain.vue

@@ -2,23 +2,20 @@
   <section class="app-main">
     <router-view v-slot="{ Component, route }">
       <transition name="fade-transform" mode="out-in">
-        <keep-alive :include="cachedViews">
-          <component :is="Component" :key="route.path"/>
+        <keep-alive :include="tagsViewStore.cachedViews">
+          <component v-if="!route.meta.link" :is="Component" :key="route.path"/>
         </keep-alive>
       </transition>
     </router-view>
+    <iframe-toggle />
   </section>
 </template>
 
 <script setup>
+import iframeToggle from "./IframeToggle/index"
 import useTagsViewStore from '@/store/modules/tagsView'
 
 const tagsViewStore = useTagsViewStore()
-const route = useRoute()
-tagsViewStore.addCachedView(route)
-const cachedViews = computed(() => {
-    return tagsViewStore.cachedViews
-})
 </script>
 
 <style lang="scss" scoped>

+ 19 - 0
src/layout/components/IframeToggle/index.vue

@@ -0,0 +1,19 @@
+<template>
+  <transition-group name="fade-transform" mode="out-in">
+    <inner-link
+      v-for="(item, index) in tagsViewStore.iframeViews"
+      :key="item.path"
+      :iframeId="'iframe' + index"
+      v-show="route.path === item.path"
+      :src="item.meta.link"
+    ></inner-link>
+  </transition-group>
+</template>
+
+<script setup>
+import InnerLink from "../InnerLink/index"
+import useTagsViewStore from '@/store/modules/tagsView'
+
+const route = useRoute();
+const tagsViewStore = useTagsViewStore()
+</script>

+ 40 - 27
src/layout/components/InnerLink/index.vue

@@ -1,30 +1,43 @@
-<script>
-export default {
-  setup() {
-    const route = useRoute();
-    const link = route.meta.link;
-    if (link === "") {
-      return "404";
-    }
-    let url = link;
-    const height = document.documentElement.clientHeight - 94.5 + "px";
-    const style = { height: height };
+<template>
+  <div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!">
+    <iframe
+      :id="iframeId"
+      style="width: 100%; height: 100%"
+      :src="src"
+      frameborder="no"
+    ></iframe>
+  </div>
+</template>
 
-    // 返回渲染函数
-    return () =>
-      h(
-        "div",
-        {
-          style: style,
-        },
-        h("iframe", {
-          src: url,
-          frameborder: "no",
-          width: "100%",
-          height: "100%",
-          scrolling: "auto",
-        })
-      );
+<script setup>
+const props = defineProps({
+  src: {
+    type: String,
+    default: "/"
   },
-};
+  iframeId: {
+    type: String
+  }
+});
+
+const height = ref(document.documentElement.clientHeight - 94.5 + "px");
+const loading = ref(false);
+
+onMounted(() => {
+    const { proxy } = getCurrentInstance()
+    const iframeId = ("#" + props.iframeId).replace(/\//g, "\\/");
+    const iframe = document.querySelector(iframeId);
+    // iframe页面loading控制
+    if (iframe.attachEvent) {
+      loading.value = true;
+      iframe.attachEvent("onload", function () {
+        proxy.loading = false;
+      });
+    } else {
+      loading.value = true;
+      iframe.onload = function () {
+        proxy.loading = false;
+      };
+    }
+})
 </script>

+ 6 - 0
src/layout/components/TagsView/index.vue

@@ -141,6 +141,9 @@ function addTags() {
   const { name } = route
   if (name) {
     useTagsViewStore().addView(route)
+    if (route.meta.link) {
+      useTagsViewStore().addIframeView(route);
+    }
   }
   return false
 }
@@ -159,6 +162,9 @@ function moveToCurrentTag() {
 }
 function refreshSelectedTag(view) {
   proxy.$tab.refreshPage(view);
+  if (route.meta.link) {
+    useTagsViewStore().delIframeView(route);
+  }
 }
 function closeSelectedTag(view) {
   proxy.$tab.closePage(view).then(({ visitedViews }) => {

+ 27 - 1
src/store/modules/tagsView.js

@@ -3,13 +3,22 @@ const useTagsViewStore = defineStore(
   {
     state: () => ({
       visitedViews: [],
-      cachedViews: []
+      cachedViews: [],
+      iframeViews: []
     }),
     actions: {
       addView(view) {
         this.addVisitedView(view)
         this.addCachedView(view)
       },
+      addIframeView(view) {
+        if (this.iframeViews.some(v => v.path === view.path)) return
+        this.iframeViews.push(
+          Object.assign({}, view, {
+            title: view.meta.title || 'no-name'
+          })
+        )
+      },
       addVisitedView(view) {
         if (this.visitedViews.some(v => v.path === view.path)) return
         this.visitedViews.push(
@@ -42,9 +51,16 @@ const useTagsViewStore = defineStore(
               break
             }
           }
+          this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
           resolve([...this.visitedViews])
         })
       },
+      delIframeView(view) {
+        return new Promise(resolve => {
+          this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
+          resolve([...this.iframeViews])
+        })
+      },
       delCachedView(view) {
         return new Promise(resolve => {
           const index = this.cachedViews.indexOf(view.name)
@@ -67,6 +83,7 @@ const useTagsViewStore = defineStore(
           this.visitedViews = this.visitedViews.filter(v => {
             return v.meta.affix || v.path === view.path
           })
+          this.iframeViews = this.iframeViews.filter(item => item.path === view.path)
           resolve([...this.visitedViews])
         })
       },
@@ -95,6 +112,7 @@ const useTagsViewStore = defineStore(
         return new Promise(resolve => {
           const affixTags = this.visitedViews.filter(tag => tag.meta.affix)
           this.visitedViews = affixTags
+          this.iframeViews = []
           resolve([...this.visitedViews])
         })
       },
@@ -126,6 +144,10 @@ const useTagsViewStore = defineStore(
             if (i > -1) {
               this.cachedViews.splice(i, 1)
             }
+            if(item.meta.link) {
+              const fi = this.iframeViews.findIndex(v => v.path === item.path)
+              this.iframeViews.splice(fi, 1)
+            }
             return false
           })
           resolve([...this.visitedViews])
@@ -145,6 +167,10 @@ const useTagsViewStore = defineStore(
             if (i > -1) {
               this.cachedViews.splice(i, 1)
             }
+            if(item.meta.link) {
+              const fi = this.iframeViews.findIndex(v => v.path === item.path)
+              this.iframeViews.splice(fi, 1)
+            }
             return false
           })
           resolve([...this.visitedViews])