mirror of
				https://github.com/dromara/RuoYi-Vue-Plus.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	优化页面内嵌iframe切换tab不刷新数据
This commit is contained in:
		@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,19 @@
 | 
			
		||||
  <section class="app-main">
 | 
			
		||||
    <transition name="fade-transform" mode="out-in">
 | 
			
		||||
      <keep-alive :include="cachedViews">
 | 
			
		||||
        <router-view :key="key" />
 | 
			
		||||
        <router-view v-if="!$route.meta.link" :key="key" />
 | 
			
		||||
      </keep-alive>
 | 
			
		||||
    </transition>
 | 
			
		||||
    <iframe-toggle />
 | 
			
		||||
  </section>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import iframeToggle from "./IframeToggle/index"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'AppMain',
 | 
			
		||||
  components: { iframeToggle },
 | 
			
		||||
  computed: {
 | 
			
		||||
    cachedViews() {
 | 
			
		||||
      return this.$store.state.tagsView.cachedViews
 | 
			
		||||
@@ -31,7 +35,7 @@ export default {
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.fixed-header+.app-main {
 | 
			
		||||
.fixed-header + .app-main {
 | 
			
		||||
  padding-top: 50px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -41,7 +45,7 @@ export default {
 | 
			
		||||
    min-height: calc(100vh - 84px);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .fixed-header+.app-main {
 | 
			
		||||
  .fixed-header + .app-main {
 | 
			
		||||
    padding-top: 84px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								ruoyi-ui/src/layout/components/IframeToggle/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ruoyi-ui/src/layout/components/IframeToggle/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <transition-group name="fade-transform" mode="out-in">
 | 
			
		||||
    <inner-link
 | 
			
		||||
      v-for="(item, index) in iframeViews"
 | 
			
		||||
      :key="item.path"
 | 
			
		||||
      :iframeId="'iframe' + index"
 | 
			
		||||
      v-show="$route.path === item.path"
 | 
			
		||||
      :src="item.meta.link"
 | 
			
		||||
    ></inner-link>
 | 
			
		||||
  </transition-group>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import InnerLink from "../InnerLink/index"
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  components: { InnerLink },
 | 
			
		||||
  computed: {
 | 
			
		||||
    iframeViews() {
 | 
			
		||||
      return this.$store.state.tagsView.iframeViews
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
@@ -1,27 +1,47 @@
 | 
			
		||||
<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>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  data() {
 | 
			
		||||
    return {};
 | 
			
		||||
  },
 | 
			
		||||
  render() {
 | 
			
		||||
    const { $route: { meta: { link } }, } = this;
 | 
			
		||||
    if ({ link }.link === "") {
 | 
			
		||||
      return "404";
 | 
			
		||||
  props: {
 | 
			
		||||
    src: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: "/"
 | 
			
		||||
    },
 | 
			
		||||
    iframeId: {
 | 
			
		||||
      type: String
 | 
			
		||||
    }
 | 
			
		||||
    let url = { link }.link;
 | 
			
		||||
    const height = document.documentElement.clientHeight - 94.5 + "px";
 | 
			
		||||
    const style = { height: height };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div style={style}>
 | 
			
		||||
        <iframe
 | 
			
		||||
          src={url}
 | 
			
		||||
          frameborder="no"
 | 
			
		||||
          style="width: 100%; height: 100%"
 | 
			
		||||
          scrolling="auto"
 | 
			
		||||
        ></iframe>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      loading: false,
 | 
			
		||||
      height: document.documentElement.clientHeight - 94.5 + "px;"
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    var _this = this;
 | 
			
		||||
    const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
 | 
			
		||||
    const iframe = document.querySelector(iframeId);
 | 
			
		||||
    // iframe页面loading控制
 | 
			
		||||
    if (iframe.attachEvent) {
 | 
			
		||||
      this.loading = true;
 | 
			
		||||
      iframe.attachEvent("onload", function () {
 | 
			
		||||
        _this.loading = false;
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      this.loading = true;
 | 
			
		||||
      iframe.onload = function () {
 | 
			
		||||
        _this.loading = false;
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -133,6 +133,9 @@ export default {
 | 
			
		||||
      const { name } = this.$route
 | 
			
		||||
      if (name) {
 | 
			
		||||
        this.$store.dispatch('tagsView/addView', this.$route)
 | 
			
		||||
        if (this.$route.meta.link) {
 | 
			
		||||
          this.$store.dispatch('tagsView/addIframeView', this.$route)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return false
 | 
			
		||||
    },
 | 
			
		||||
@@ -153,6 +156,9 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    refreshSelectedTag(view) {
 | 
			
		||||
      this.$tab.refreshPage(view);
 | 
			
		||||
      if (this.$route.meta.link) {
 | 
			
		||||
        this.$store.dispatch('tagsView/delIframeView', this.$route)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    closeSelectedTag(view) {
 | 
			
		||||
      this.$tab.closePage(view).then(({ visitedViews }) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,17 @@
 | 
			
		||||
const state = {
 | 
			
		||||
  visitedViews: [],
 | 
			
		||||
  cachedViews: []
 | 
			
		||||
  cachedViews: [],
 | 
			
		||||
  iframeViews: []
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const mutations = {
 | 
			
		||||
  ADD_IFRAME_VIEW: (state, view) => {
 | 
			
		||||
    if (state.iframeViews.some(v => v.path === view.path)) {
 | 
			
		||||
      return
 | 
			
		||||
    } else {
 | 
			
		||||
      state.iframeViews.push(view)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  ADD_VISITED_VIEW: (state, view) => {
 | 
			
		||||
    if (state.visitedViews.some(v => v.path === view.path)) return
 | 
			
		||||
    state.visitedViews.push(
 | 
			
		||||
@@ -18,7 +26,6 @@ const mutations = {
 | 
			
		||||
      state.cachedViews.push(view.name)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  DEL_VISITED_VIEW: (state, view) => {
 | 
			
		||||
    for (const [i, v] of state.visitedViews.entries()) {
 | 
			
		||||
      if (v.path === view.path) {
 | 
			
		||||
@@ -26,6 +33,10 @@ const mutations = {
 | 
			
		||||
        break
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
 | 
			
		||||
  },
 | 
			
		||||
  DEL_IFRAME_VIEW: (state, view) => {
 | 
			
		||||
    state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
 | 
			
		||||
  },
 | 
			
		||||
  DEL_CACHED_VIEW: (state, view) => {
 | 
			
		||||
    const index = state.cachedViews.indexOf(view.name)
 | 
			
		||||
@@ -36,6 +47,7 @@ const mutations = {
 | 
			
		||||
    state.visitedViews = state.visitedViews.filter(v => {
 | 
			
		||||
      return v.meta.affix || v.path === view.path
 | 
			
		||||
    })
 | 
			
		||||
    state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
 | 
			
		||||
  },
 | 
			
		||||
  DEL_OTHERS_CACHED_VIEWS: (state, view) => {
 | 
			
		||||
    const index = state.cachedViews.indexOf(view.name)
 | 
			
		||||
@@ -45,16 +57,15 @@ const mutations = {
 | 
			
		||||
      state.cachedViews = []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  DEL_ALL_VISITED_VIEWS: state => {
 | 
			
		||||
    // keep affix tags
 | 
			
		||||
    const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
 | 
			
		||||
    state.visitedViews = affixTags
 | 
			
		||||
    state.iframeViews = []
 | 
			
		||||
  },
 | 
			
		||||
  DEL_ALL_CACHED_VIEWS: state => {
 | 
			
		||||
    state.cachedViews = []
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  UPDATE_VISITED_VIEW: (state, view) => {
 | 
			
		||||
    for (let v of state.visitedViews) {
 | 
			
		||||
      if (v.path === view.path) {
 | 
			
		||||
@@ -63,7 +74,6 @@ const mutations = {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  
 | 
			
		||||
  DEL_RIGHT_VIEWS: (state, view) => {
 | 
			
		||||
    const index = state.visitedViews.findIndex(v => v.path === view.path)
 | 
			
		||||
    if (index === -1) {
 | 
			
		||||
@@ -79,8 +89,9 @@ const mutations = {
 | 
			
		||||
      }
 | 
			
		||||
      return false
 | 
			
		||||
    })
 | 
			
		||||
    const iframeIndex = state.iframeViews.findIndex(v => v.path === view.path)
 | 
			
		||||
    state.iframeViews = state.iframeViews.filter((item, idx) => idx <= iframeIndex)
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  DEL_LEFT_VIEWS: (state, view) => {
 | 
			
		||||
    const index = state.visitedViews.findIndex(v => v.path === view.path)
 | 
			
		||||
    if (index === -1) {
 | 
			
		||||
@@ -96,6 +107,8 @@ const mutations = {
 | 
			
		||||
      }
 | 
			
		||||
      return false
 | 
			
		||||
    })
 | 
			
		||||
    const iframeIndex = state.iframeViews.findIndex(v => v.path === view.path)
 | 
			
		||||
    state.iframeViews = state.iframeViews.filter((item, idx) => idx >= iframeIndex)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -104,13 +117,15 @@ const actions = {
 | 
			
		||||
    dispatch('addVisitedView', view)
 | 
			
		||||
    dispatch('addCachedView', view)
 | 
			
		||||
  },
 | 
			
		||||
  addIframeView({ commit }, view) {
 | 
			
		||||
    commit('ADD_IFRAME_VIEW', view)
 | 
			
		||||
  },
 | 
			
		||||
  addVisitedView({ commit }, view) {
 | 
			
		||||
    commit('ADD_VISITED_VIEW', view)
 | 
			
		||||
  },
 | 
			
		||||
  addCachedView({ commit }, view) {
 | 
			
		||||
    commit('ADD_CACHED_VIEW', view)
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  delView({ dispatch, state }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      dispatch('delVisitedView', view)
 | 
			
		||||
@@ -127,13 +142,18 @@ const actions = {
 | 
			
		||||
      resolve([...state.visitedViews])
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  delIframeView({ commit, state }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      commit('DEL_IFRAME_VIEW', view)
 | 
			
		||||
      resolve([...state.iframeViews])
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  delCachedView({ commit, state }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      commit('DEL_CACHED_VIEW', view)
 | 
			
		||||
      resolve([...state.cachedViews])
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  delOthersViews({ dispatch, state }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      dispatch('delOthersVisitedViews', view)
 | 
			
		||||
@@ -156,7 +176,6 @@ const actions = {
 | 
			
		||||
      resolve([...state.cachedViews])
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  delAllViews({ dispatch, state }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      dispatch('delAllVisitedViews', view)
 | 
			
		||||
@@ -179,18 +198,15 @@ const actions = {
 | 
			
		||||
      resolve([...state.cachedViews])
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  updateVisitedView({ commit }, view) {
 | 
			
		||||
    commit('UPDATE_VISITED_VIEW', view)
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  delRightTags({ commit }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      commit('DEL_RIGHT_VIEWS', view)
 | 
			
		||||
      resolve([...state.visitedViews])
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  delLeftTags({ commit }, view) {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
      commit('DEL_LEFT_VIEWS', view)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user