若依框架前端切换TagView时刷新问题

若依框架点击顶部tag切换时,永远都是刷新的。刷新问题两种情况:普通view切换时刷新及iFrame切换刷新
一、普通view切换时刷新

原因是view的name与在菜单填写的大小写不一致,按若依框架规则,路由地址必须写为 camel 驼峰命名形式,组件名称必须写为 pascal首字母全大写的形式。

参考:若依 | 点击顶部 tag 标签不自动刷新 - shayloyuki - 博客园

二、iFrame切换刷新问题

 原因是iframe无法通过keep-alive缓存内容节点,每次都需要重新渲染刷新,iframe中keep-alive机制失效原因:iframe页里的内容并不属于节点的信息,所以使用keep-alive依然会重新渲染iframe内的内容。而且iframe每一次渲染就相当于打开一个新的网页窗口,即使把节点保存下来,在渲染时iframe页还是刷新的。

参考:1.vue中keep-alive对引入iframe的页面无效,实现iframe页面缓存问题_vue iframe 缓存_ll7425的博客-CSDN博客

2.GitHub - jmx164491960/vue-iframe-demo: 在vue中实现iframe keep-alive

解决思路:
route-link点击切换时用route-view渲染呈现,若component为空时则不呈现,可以增加一个iframe组件在route-view旁边,同时监听路由,若是需要iframe呈现则显示,置空component,并给予iframe的src链接就完成呈现,再控制切换时用v-show控制显示当前路由即可。

改造若依步骤:
1.在获取路由时,判断iframe标识的置空component,打开文件src\store\modules\permission.js

 

2.改造route-view呈现iframe内容 (暂时没空分析,不懂的加好友提问吧,把代码贴上来)

修改文件src\layout\components\AppMain.vue

<template>

  <section class="app-main">

    <transition name="fade-transform" mode="out-in">

      <keep-alive :include="cachedViews">

        <router-view :key="key" />

      </keep-alive>

    </transition>

    <!-- iframe页 -->

    <iframe v-for="item in componentsArr" :ref="item.name" :id="item.name" frameborder="no"

      :style="'width: 100%; height:' +height" scrolling="auto" v-show="$router.currentRoute.path.endsWith(item.path)"/>

  </section>

</template>



<script>

import Cookies from "js-cookie";



export default {

  name: "AppMain",

  data() {

    return {

      componentsArr: [],

      height: document.documentElement.clientHeight - 94.5 + "px;",

    };

  },

  created() {

    // 设置iframe页的数组对象

    const componentsArr = this.getComponentsArr();    

    this.componentsArr = componentsArr;

    // 判断当前路由是否iframe页

    setTimeout(() => {

      this.isOpenIframePage();

    }, 200);    

  },

  mounted: function () {

    setTimeout(() => {

      this.loading = false;

    }, 300);

    const that = this;

    window.onresize = function temp() {

      that.height = document.documentElement.clientHeight - 94.5 + "px;";

    };

  },

  computed: {

    cachedViews() {

      return this.$store.state.tagsView.cachedViews;

    },

    key() {

      return this.$route.path;

    },    

  },



  watch: {

    $route() {

      // 判断当前路由是否iframe页

      this.isOpenIframePage();

    },

  },

  methods: {

    // 根据当前路由设置hasOpen

    isOpenIframePage() {  

      debugger;  

      var path = this.$router.currentRoute.path.split("/").pop();      

      var iframe=this.$refs[path];

      if(iframe)

      {

        iframe=iframe[0];

      }

      if (iframe&&!iframe.isbindsrc) {

        this.code = this.$router.currentRoute.query.code;

        let menuId = this.$router.currentRoute.meta.menuId;

        let uuid = Cookies.get("uuid");

        let menuCode = this.$router.currentRoute.meta.menuCode;

        let link =

          this.$router.currentRoute.meta.frameAddress ||

          "/yizumiapi/yisee/tabs2";

        if (link.indexOf("?") >= 0) {

          link += "&";

        } else {

          link += "?";

        }

        let url =

          link + "menuId=" + menuId + "&uuid=" + uuid + "&mcode=" + menuCode;



          iframe.src = url;

          iframe.isbindsrc="true"

      }

    },

    // 遍历路由的所有页面,把含有iframeComponent标识的收集起来

    getComponentsArr() {

      const routers = this.$store.state.permission.iframeRoutes; //this.$router;

      //const routers = router.options.routes;

      var iframeMenus = [];

      var genMenus = (routes) => {

        routes.forEach((item, index) => {

          if (item.meta && item.meta.frameAddress) {

            var it = Object.assign(item);

            delete it.children;           

            iframeMenus.push(it);

          }

          if (item.children) {

            genMenus(item.children);

          }

        });

      };



      genMenus(routers);

      return iframeMenus;

    },

  },

};

</script>



<style lang="scss" scoped>

.app-main {

  /* 50= navbar  50  */

  min-height: calc(100vh - 50px);

  width: 100%;

  position: relative;

  overflow: hidden;

}



.fixed-header+.app-main {

  padding-top: 50px;

}



.hasTagsView {

  .app-main {

    /* 84 = navbar + tags-view = 50 + 34 */

    min-height: calc(100vh - 84px);

  }



  .fixed-header+.app-main {

    padding-top: 84px;

  }

}

</style>



<style lang="scss">

// fix css style bug in open el-dialog

.el-popup-parent--hidden {

  .fixed-header {

    padding-right: 17px;

  }

}

</style>

src\store\modules\permission.js 代码

import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'


const permission = {
  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: [],
    iframeRoutes: [],
  },
  mutations: {
    SET_ROUTES: (state, routes) => {     
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      state.defaultRoutes = constantRoutes.concat(routes)
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes
    },
    SET_IFRAME_ROUTERS: (state, routes) => {
      state.iframeRoutes = routes
    },
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit },appId) {
      return new Promise(resolve => {
        // 向后端请求路由数据
        getRouters(appId).then(res => {
          const sdata = JSON.parse(JSON.stringify(res.data))
          const rdata = JSON.parse(JSON.stringify(res.data))
          const sidebarRoutes = filterAsyncRouter(sdata)
          const rewriteRoutes = filterAsyncRouter(rdata, false, true)
          const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
          rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })         
          router.addRoutes(asyncRoutes);
          commit('SET_ROUTES', rewriteRoutes)
          commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
          commit('SET_DEFAULT_ROUTES', sidebarRoutes)
          commit('SET_TOPBAR_ROUTES', sidebarRoutes)
          debugger;         
          commit('SET_IFRAME_ROUTERS', iframeRoutes)
          resolve(rewriteRoutes)
        })
      })
    }
  }
}
var iframeRoutes=[];
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter(route => {
    if (type && route.children) {
      route.children = filterChildren(route.children)
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout
      } else if (route.component === 'ParentView') {
        route.component = ParentView
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink
      } else {
        if(route.meta&&route.meta.frameAddress)
        {
          route.component=undefined;
          if(iframeRoutes.filter(c=>c.name==route.name).length==0)
          {iframeRoutes.push(route)}
        }
        else{
        route.component = loadView(route.component)
        }
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
    } else {
      delete route['children']
      delete route['redirect']
    }
    return true
  })
}

function filterChildren(childrenMap, lastRouter = false) {
  var children = []
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === 'ParentView' && !lastRouter) {
        el.children.forEach(c => {
          c.path = el.path + '/' + c.path
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c))
            return
          }
          children.push(c)
        })
        return
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + '/' + el.path
    }
    children = children.concat(el)
  })
  return children
}

// 动态路由遍历,验证是否具备权限
export function filterDynamicRoutes(routes) {
  const res = []
  routes.forEach(route => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route)
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route)
      }
    }
  })
  return res
}

export const loadView = (view) => {
  if (process.env.NODE_ENV === 'development') {
    return (resolve) => require([`@/views/${view}`], resolve)
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return () => import(`@/views/${view}`)
  }
}

export default permission

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值