首页 > 编程 > JavaScript > 正文

Vue集成Iframe页面的方法示例

2019-11-19 14:44:51
字体:
来源:转载
供稿:网友

1. 项目需求

我们切换为vue框架是后面的事情,之前还有一些功能页面是用jsp页面写的,而我们的管理系统需要既支持Vue的url,又要支持这些发布之后的jsp页面

还有一个就是切换tab回来的时候之前输入的东西还要存在

系统页面截图

2. 实现思路

针对这个问题,我们最开始的实现思路是写了一个iframe的通用组件,然后把不同的http的页面的url传递进来进行切换,但是这样不满足第二条,我们发现只要切换了vue的路由,然后再切回http的页面,iframe中的src属性的页面就会从新刷新,没有办法保留住东西,于是就有了下面的实现思路

我们在vue的router-view同级别添加了一个iframeTemp组件,其实就是一个elementUI的tab组件,然后把tab组件的头的样式隐藏在我们菜单栏的下面

<template> <!--路由渲染的功能模块区域--> <div class="router-out-content">  <!--缓存部分页面的写法-->  <keep-alive>   <router-view v-show="!showIframe" class="position router-content" v-if="$route.meta.keepAlive"></router-view>  </keep-alive>  <router-view v-show="!showIframe" class="position router-content" v-if="!$route.meta.keepAlive"></router-view>  <!--兼容系统外部页面-->  <iframe-temp v-show="showIframe"></iframe-temp> </div></template><style scoped lang="scss"> .position {  position: relative } .router-out-content {  position: static; }</style><script>import { mapState } from 'vuex'import iframeTemp from '@/containers/main/IframeTemplate.vue'export default { data() {  return {} }, components: {  iframeTemp }, computed: {  ...mapState([   'showIframe'  ]) }}</script>
/* * IframeTemplate.vue组件的内部 **/ <template> <!--iframe页面展示区域--> <div id="fwIframe">  <!--<Tabs class="full temporary-tabs" v-model="store.state.iframeSelectTab" type="card">-->  <Tabs class="full temporary-tabs" :value="iframeSelectTab" type="card">   <TabPane    v-for="(item, index) in iframeTabData"    :key="item.tag"    :label="item.name"    :name="item.tag"   >    <iframe :key="item.tag" v-once :src="item.url" frameborder="0"></iframe>   </TabPane>  </Tabs> </div></template><style lang="scss"> #fwIframe {  /*测试位置的时候显示这段--开始*/  /*width: 100%;*/  /*height: 100%;*/  /*background-color: red;*/  /*display: block !important;*/  /*测试位置的时候显示这段--结束*/  position: absolute;  left: 0;  right: 0;  top: 45px;  bottom: 0;  z-index: 5000 !important;  .el-tab-pane {   height: 100%;   width: 100%;   iframe {    /*height: auto;*/    min-height: 600px;    /*height: calc(100% - 45px);*/    width: 100%;   }  }  .full {   position: relative;   left: 0;   right: 0;   top: 0;   bottom: 0;  } }</style><script> // selectTabCode=>iframeSelectTab // tabsList=>iframeTabData import {mapState} from 'vuex' import * as mainConst from '@/store/mainConst.js' export default{  data(){   return {//    tabsList: [],//    selectTabCode: ''   }  },  computed: {   ...mapState([    'iframeTabData',    'iframeSelectTab',    'navTabData',    'systemName'   ])  },  mounted(){   const _this = this   // 1、监听添加iframe中tab的广播   this.$root.bus.$on('addIframeTab', function (item) {    // _this.tabsList.push(item)    // _this.selectTabCode = item.tag    _this.$store.commit(mainConst.M_IFRAME_PUSH_TAB, item)    _this.$store.commit(mainConst.M_IFRAME_CHANGE_SELECTCODE, item.tag)   })   // 2、监听切换iframe中tab的广播   this.$root.bus.$on('changeIframeTab', function (tag) {    _this.$store.commit(mainConst.M_IFRAME_CHANGE_SELECTCODE, tag)   })   // 3、监听删除iframe中tab的广播   this.$root.bus.$on('deleteIframeTab', function (obj) {    // 1、删除iframe中的指定tab页面    _this.$store.commit(mainConst.M_IFRAME_DELETE_TAB, obj)    // _this.tabsList = _this.tabsList.filter(tab => tab.tag !== obj.tag)    // 2、如果删除的一级tab不是当前激活的一级tab,TabsTemeplate中的一级tab删除事件已经在vuex中删除了,不需要做路由跳转操作了    let index = obj.index    for (let i = 0; i < _this.navTabData.length; i++) {     if (_this.navTabData[i].active) {      return     }    }    // 3、如果删除的一级tab是当前激活的一级tab,    const con = _this.navTabData[index - 1] || _this.navTabData[index]    let url = `/${_this.systemName}`    if (con) {     // 还有其他的一级tab,就赋值其他的一级tab的url,探后跳转     url = con.url     con.active = true     // 如果还有其他一级的tab,那么还要判断跳转的页面是不是iframe     if (url.toLowerCase().indexOf("/iframe") == 0) {      // 如果是iframe页面,显示iframe,广播iframe的切换tab切换事件,路由进行跳转      _this.$store.commit(mainConst.M_SHOW_IFRAME)      _this.$root.bus.$emit("changeIframeTab", url.slice(8))     } else {      // 如果不是iframe页面,隐藏iframe,路由进行跳转      _this.$store.commit(mainConst.M_HIDE_IFRAME)      // _this.$store.commit(mainConst.M_UPDATE_NAVTABDATA, {navIndex: index})     }    }    else {     // 没有其他的一级tab,直接隐藏iframe,跳首页     _this.$store.commit(mainConst.M_HIDE_IFRAME)    }    _this.$router.push(url)   })  } }</script>

之后的ifram组件的显示隐藏和tab切换,都是通用vuex和bus事件广播实现的

/* * mainConst.js **//*****************************getter常量****************************************/export const G_GET_NAVTABDATA = 'G_GET_NAVTABDATA'/*****************************mutations常量*************************************/// 一级tab处理export const M_PUSH_NAVTABDATA = 'M_PUSH_NAVTABDATA'export const M_DELETE_NAVTABDATA = 'M_DELETE_NAVTABDATA'export const M_UPDATE_NAVTABDATA = 'M_UPDATE_NAVTABDATA'// iframe切换处理export const M_SHOW_IFRAME = 'M_SHOW_IFRAME'export const M_HIDE_IFRAME = 'M_HIDE_IFRAME'// iframe添加,删除,选择处理export const M_IFRAME_PUSH_TAB='M_IFRAME_PUSH_TAB'export const M_IFRAME_DELETE_TAB='M_IFRAME_DELETE_TAB'export const M_IFRAME_CHANGE_SELECTCODE='M_IFRAME_CHANGE_SELECTCODE'// 设置全局系统变量export const M_SET_SYSTEMNAME = 'M_SET_SYSTEMNAME'/*****************************actions常量***************************************/// export const A_REQUEST_DATA = 'A_REQUEST_DATA'
/* * mainModule.js **/import * as mainConst from './mainConst.js'export default { state: {  // 一级Tab导航数据集合  navTabData: [],  // 进入的主系统前缀  systemName:'',  // 控制路由同级的Iframe的显示隐藏  showIframe: false,  // iframe页面中的选中页签的code值  iframeSelectTab:'',  // iframe页面的tab数据集合  iframeTabData:[] }, getters: {  [mainConst.G_GET_NAVTABDATA](state, getters){   return state.navTabData  } }, mutations: {  // 一级tab处理  [mainConst.M_UPDATE_NAVTABDATA](state, payload){   const index = payload.navIndex   state.navTabData.forEach((item)=> {    item.active = false   })   // 当你利用索引直接设置一个项时是不能触发视图的从新渲染的,下面是老方法和解决办法   // state.navTabData[index].active=true   let newItem = Object.assign({}, state.navTabData[index], {active: true})   // console.log(newItem, 'store newItem')   state.navTabData.splice(index, 1, newItem)  },  [mainConst.M_PUSH_NAVTABDATA] (state, payload) {   state.navTabData.push(payload)  },  [mainConst.M_DELETE_NAVTABDATA] (state, payload) {   state.navTabData.splice(payload.navIndex, 1)  },  // Iframe显示隐藏切换处理  [mainConst.M_SHOW_IFRAME] (state, payload) {   state.showIframe = true  },  [mainConst.M_HIDE_IFRAME] (state, payload) {   state.showIframe = false  },  // Iframe添加,删除,选中处理  [mainConst.M_IFRAME_PUSH_TAB] (state, payload) {   state.iframeTabData.push(payload)  },  [mainConst.M_IFRAME_DELETE_TAB] (state, payload) {   state.iframeTabData = state.iframeTabData.filter(tab => tab.tag !== payload.tag)  },  [mainConst.M_IFRAME_CHANGE_SELECTCODE] (state, payload) {   state.iframeSelectTab=payload  },  // 设置全局system变量  [mainConst.M_SET_SYSTEMNAME] (state, payload) {   state.systemName=payload  } }, actions: {  // actions的最终功能是修改state,但是它不直接修改state,而是调用mutations  // async [aboutConst.A_REQUEST_DATA]({dispatch,commit}) {  //  commit(aboutMutations.REQUEST_LOADING)  //  await service.getMovieListData('{"movieType":"in_theaters","pageIndex":2,"start":0,"count":10}')  //  console.log(333333)  //  await function(){setTimeout(function () {  //   commit(aboutMutations.REQUEST_FAILD)  //  },6000)}()  //  console.log(66666)  // }  // actions的最终功能是修改state,但是它不直接修改state,而是调用mutations  // async [aboutConst.A_REQUEST_DATA]({dispatch,commit}) {  //  commit(aboutMutations.REQUEST_LOADING)  //  await service.getMovieListData('{"movieType":"in_theaters","pageIndex":2,"start":0,"count":10}')  //  console.log(333333)  //  await function(){setTimeout(function () {  //   commit(aboutMutations.REQUEST_FAILD)  //  },6000)}()  //  console.log(66666)  // } }}
/* * 三级菜单的点击处理 **/<template> <!--三级菜单导航功能--> <div class="main-nav f14 clearfix" @mouseleave="funMenu.menuIsShow=false">  <div class="f_l lt-tab">   <ul class="l-nav clearfix">    <li class="main f_l">     <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="f16 fun" @click="getMainMenu">功能导航</a>     <div class="more-menu clearfix" v-show="funMenu.firstMenu.length&&funMenu.menuIsShow">      <!--一级导航-->      <ul class="first-menu f_l">       <li v-for="(item,index) in funMenu.firstMenu" @mouseover="clickByMenu($event,item,'firstMenu')">        <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" :class="{active:item.active}" :index="index">{{item.resourceName}}</a>       </li>      </ul>      <!--二级导航-->      <ul class="next-menu f_l" v-show="funMenu.nextMenu.length">       <li        v-for="(item,index) in funMenu.nextMenu"        @mouseover="clickByMenu($event,item,'nextMenu')"        @click="clickMenuJump(funMenu.nextMenu, item)"       >        <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" :class="{active:item.active}" :index="index">{{item.resourceName}}</a>       </li>      </ul>      <!--三级导航-->      <!--存在四级导航-->      <div class="last-menu f_l dl" v-show="funMenu.lastMenu.length">       <div v-for="(item,index) in funMenu.lastMenu" class="dt">        <div v-if="item.childFuncs.length">         <span>{{item.resourceName }}</span>         <ul class="dd">          <li v-for="(item,index) in item.childFuncs"           @click="clickByMenu($event,item,'lastMenu')">           <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >{{item.resourceName}}</a>           <!--:class="{active:item.active}"-->          </li>         </ul>        </div>        <!--三级导航可点击-->        <div v-else>         <ul class="dd">          <li @click="clickByMenu($event,item,'lastMenu')">           <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >{{item.resourceName}}</a>           <!--:class="{active:item.active}"-->          </li>         </ul>        </div>       </div>      </div>     </div>    </li>    <li class="nav-index f_l">     <!--<router-link :to="'/'+$store.state.systemName">首页</router-link>-->     <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="goHome">首页</a>    </li>   </ul>  </div> </div></template><style scoped lang="scss"> .main-nav {  position: relative;  height: 42px;  line-height: 42px;  background: #eee;  border-bottom: 1px solid #ddd; } .main-nav a {  color: #303e51;  text-decoration: none; } .main-nav a:hover {  color: #438eb9; } .main-nav .main {  /*padding: 0 16px;*/  text-align: center;  border-right: 1px solid #ddd;  position: relative;  background: #eee;  width: 122px; } .main-nav .main.active, .main-nav .main:hover {  background: white; } .main-nav .more-menu {  position: fixed;  top: 84px;  left: 0;  max-height: 500px;  bottom: 124px;  z-index: 998;  background: #fff;  border: 1px solid #ddd;  border-left: none;  border-top: 0;  overflow: hidden;  box-shadow: 1px 1px 10px #ddd; } .main-nav .more-menu ul, .main-nav .more-menu .dl {  text-align: left;  overflow: auto; } .main-nav .more-menu a {  font-size: 14px;  color: #303e51;  text-decoration: none; } .main-nav .more-menu a:hover, .main-nav .more-menu a.active {  color: rgb(46, 167, 224); } .main-nav .more-menu .first-menu {  height: 100%;  border-right: 1px solid #ddd;  box-shadow: -1px 0px 5px #ddd inset;  /*width: 138px;*/ } .main-nav .more-menu .first-menu li {  height: 36px;  line-height: 36px;  margin: 0 15px 0 6px;  min-width: 94px; } .main-nav .more-menu .first-menu a {  display: block;  background: url(../../asserts/images/home/main/icon_1.png) no-repeat 5px center;  width: 100%;  height: 100%;  border-bottom: 1px solid #dddddd;  padding-left: 20px;  box-sizing: border-box;  text-overflow: ellipsis;  overflow: hidden;  white-space: nowrap;  text-indent: 5px; } .main-nav .more-menu .first-menu a.active, .main-nav .more-menu .first-menu a:hover {  background: url(../../asserts/images/home/main/icon_2.png) no-repeat 5px center rgb(46, 167, 224);  color: white;  border: 0; } .main-nav .more-menu .next-menu {  height: 100%;  border-right: 1px solid #ddd;  box-shadow: -1px 0px 5px #ddd inset;  /*width: 138px;*/  line-height: 14px; } .main-nav .more-menu .next-menu li:first-child {  margin-top: 10px; } .main-nav .more-menu .next-menu li {  margin-bottom: 16px;  margin-left: 16px; } .main-nav .more-menu .next-menu li a {  border-left: 2px solid transparent;  padding-left: 10px;  margin-right: 24px; } .main-nav .more-menu .next-menu li a:hover, .main-nav .more-menu .next-menu li a.active {  border-left: 2px solid rgb(46, 167, 224); } .main-nav .more-menu .last-menu {  height: 100%;  min-width: 288px;  line-height: 14px; } .main-nav .more-menu .last-menu .dt {  margin-left: 16px;  margin-top: 10px;  span {   color: #566678;  } } .main-nav .more-menu .last-menu .dd {  color: #7a8897;  margin-top: 16px;  margin-left: 4px;  > li {   margin-bottom: 16px;   a {    border-left: 2px solid transparent;    padding-left: 6px;    margin-right: 16px;    &:hover, &.active {     border-color: #2ea7e0;    }   }  } } /*.main-nav .more-menu .last-menu dd a:hover,.main-nav .more-menu .last-menu dd a.active{*/ /*border-left: 2px solid rgb(46,167,224);*/ /*}*/ .main-nav .main .fun {  width: 100%;  height: 100%;  display: block; } .main-nav .main .fun:before {  content: "";  width: 18px;  height: 18px;  background: url("../../asserts/images/home/main/icon-all.png");  background-position: -89px -7px;  display: inline-block;  margin-right: 10px;  margin-top: 2px;  vertical-align: text-top; } .main-nav .l-nav {  z-index: 2; } .main-nav .nav-index {  width: 90px;  text-align: center;  position: relative;  background: #eee; } .main-nav .nav-index:after {  content: "";  width: 8px;  height: 40px;  background: url(../../asserts/images/home/main/shadow-l.png);  position: absolute;  top: 2px;  left: 90px; } .main-nav .lt-tab {  position: absolute;  left: 0;  z-index: 2;  border-bottom: 1px solid #ddd; } /*tab--------*/ .main-nav .ct-tab {  position: absolute;  z-index: 1;  left: 213px;  width: 10000000px; } .main-nav .ct-tab .ct-ul { } .main-nav .ct-tab .ct-ul li {  position: relative;  float: left; } .main-nav .ct-tab .ct-ul li a {  height: 24px;  line-height: 24px;  margin: 9px 0;  min-width: 90px;  /*max-width: 190px;*/  border-right: 1px solid #ddd;  display: block;  text-align: center;  position: relative; } .main-nav .ct-tab .ct-ul li a i {  display: none; } .main-nav .ct-tab .ct-ul li a i {  display: none; } .main-nav .ct-tab .ct-ul li a .content {  display: block;  max-width: 190px;  overflow: hidden;  text-overflow: ellipsis;  white-space: nowrap; } .main-nav .ct-tab .ct-ul li a:hover {  z-index: 1; } .main-nav .ct-tab .ct-ul li:first-child a:hover, .main-nav .ct-tab li:first-child a.active {  margin-left: 0;  margin-right: 0; } .main-nav .ct-tab .ct-ul li a:hover, .main-nav .ct-tab li a.active {  max-width: 250px;  display: block;  text-align: center;  position: relative;  border: 0;  margin: 0 -20px;  margin-top: 4px;  color: black;  padding: 0; } .main-nav .ct-tab .padding {  width: auto;  padding: 0 16px; } .main-nav .ct-tab .ct-ul li a:hover > i, .main-nav .ct-tab .ct-ul li a.active > i {  display: inline-block;  width: 34px;  height: 37px;  float: left; } .main-nav .ct-tab .ct-ul li a:hover .line-l {  background: url(../../asserts/images/home/main/line_left.png) no-repeat; } .main-nav .ct-tab .ct-ul li a:hover .line-r {  background: url(../../asserts/images/home/main/line_right.png) no-repeat; } .main-nav .ct-tab .ct-ul li a.active .line-l {  background: url(../../asserts/images/home/main/line_sel_left.png) no-repeat; } .main-nav .ct-tab .ct-ul li a.active .line-r {  background: url(../../asserts/images/home/main/line_sel_right.png) no-repeat; } .main-nav .ct-tab .ct-ul li a:hover .content, .main-nav .ct-tab li a.active .content {  border-top: 1px solid #ddd;  float: left;  line-height: 36px;  min-width: 60px;  max-width: 150px;  overflow: hidden;  text-overflow: ellipsis;  white-space: nowrap;  background: rgb(245, 245, 245); } .main-nav .ct-tab .ct-ul li a:hover .cha, .main-nav .ct-tab .ct-ul li a.active .cha {  background: rgb(245, 245, 245);  width: 20px;  height: 36px;  line-height: 36px;  border-top: 1px solid #ddd;  padding-left: 7px;  color: #303e51; } .main-nav .ct-tab .ct-ul li a.active .content, .main-nav .ct-tab .ct-ul li a.active .cha {  background: white; } .main-nav .ct-tab .ct-ul li a .cha {  color: #eee; } .main-nav .ct-tab .ct-ul li a .cha:hover {  color: black; } .main-nav .ct-tab .ct-ul li a.active {  z-index: 2; }</style><script> import axios from 'axios' import { mapState} from 'vuex' import * as mainConst from '@/store/mainConst.js' import config from '@/config/index.js' import storage from '@/utils/storage.js' export default{  data(){   return {    funMenu: {     // 一级菜单     firstMenu: [],     // 二级菜单     nextMenu: [],     // 三级菜单     lastMenu: [],     // 是否显示     menuIsShow: true    }   }  },  computed: mapState({   // 箭头函数可使代码更简练   funcMenuList: state => state.funcMenuList,  }),  methods: {   // 跳转首页   goHome(){    // 跳转首页就关闭iframe    this.$store.commit(mainConst.M_HIDE_IFRAME)    this.$router.push(`/${this.$store.state.systemName}`)   },   // ★★★★★调用方法获取三级菜单列表★★★★★   getMainMenu(){    var _this = this    if (this.funMenu.firstMenu.length) {     this.funMenu.menuIsShow = true    } else {     if (config.setting.funcMenu) {      _this.funMenu.firstMenu = storage.getItem('hivescm.userAuthor').menus.funcs     } else {      axios.get("data/menu_json.json")       .then(function (res) {        _this.funMenu.firstMenu = res.data.result.funcs       })     }    }   },   // 点击菜单展开下一级别列表事件   clickByMenu(e, menuItem, level){    let menuList = this.funMenu[level]    switch (level) {     case "firstMenu": {      this.funMenu.nextMenu = this.getFirstAndNextVal(menuList, menuItem)      this.funMenu.lastMenu = []     }      break     case "nextMenu": {      if (!menuItem.url.length) this.funMenu.lastMenu = this.getFirstAndNextVal(menuList, menuItem)//      menuItem.url.length ? this.clickMenuJump(menuList, menuItem) : this.funMenu.lastMenu = this.getFirstAndNextVal(menuList, menuItem)     }      break     case "lastMenu": {      this.clickMenuJump(menuList, menuItem)     }      break    }   },   // ★★★★★点击有url的菜单,跳转事件★★★★★   clickMenuJump(menuList, menuItem){    if (!menuItem.url.length) return    this.funMenu.menuIsShow = false    this.lastmenuChange(menuList, menuItem)    let iframeTabItem = {}    // 1、路由跳转和iframe的显示隐藏    if (menuItem.url.toLowerCase().indexOf("/") != 0 || menuItem.url.toLowerCase().indexOf("/iframe") == 0) {     // 判断如果是iframe的url,显示iframe     // 定义一个新的item对象,防止对象的引用     iframeTabItem = Object.assign({}, menuItem)     this.$store.commit(mainConst.M_SHOW_IFRAME)     // 待优化:应该有优化为手动赋值样式     // (1)、此处利用router-view的特性,让一级tab变颜色     // (2)、这个还是控制一级tab点击切换tab标签的重要因素     // 因为原始的iframe的url已经改变,所以要保存到一个新的变量里面,如果已经有了就不需要在放了     if (!menuItem.iframeUrl) {      menuItem.iframeUrl = menuItem.url      let userId = storage.getItem('hivescm.userAuthor').id      let token = storage.getItem('hivescm.userAuthor').token      iframeTabItem.url = `${menuItem.url}?userId=${userId}&token=${token}`     } else {      let userId = storage.getItem('hivescm.userAuthor').id      let token = storage.getItem('hivescm.userAuthor').token      iframeTabItem.url = `${menuItem.iframeUrl}?userId=${userId}&token=${token}`      console.log(iframeTabItem.url)//      iframeTabItem.url = menuItem.iframeUrl     }     menuItem.url = `/iframe/${menuItem.tag}`     this.$router.push(`/iframe/${menuItem.tag}`)    } else {     // 判断如果是spa的url,隐藏iframe     this.$store.commit(mainConst.M_HIDE_IFRAME)     menuItem.url=`${menuItem.url}?permissionId=${menuItem.permissionId}`     this.$router.push({path:menuItem.url,query:{permissionId:menuItem.permissionId}})    }    // 2、判断vuex中是否有重复的tab标签    let navTabData = this.$store.state.navTabData    for (let i = 0; i < navTabData.length; i++) {     if (navTabData[i].url == menuItem.url) {      // 已经有页签了,一级tab内容不重新渲染      // 切换一级tab页签的激活样式      this.$store.commit(mainConst.M_UPDATE_NAVTABDATA, {navIndex: i})      // 从新计算一级tab位置      this.$root.bus.$emit("clickLastMenu", menuItem)      if (menuItem.url.toLowerCase().indexOf("/iframe") == 0) {       // 如果已经iframe中的tab已经存在,那么触发iframe中的切换事件//       this.$store.commit(mainConst.M_SHOW_IFRAME)       this.$root.bus.$emit("changeIframeTab", menuItem.url.slice(8))      }      return     }    }    // 3、向vuex中添加一级tab    // 默认是否选中    menuItem.active = true    // 向一级tab中添加新的tab标签    this.$store.commit(mainConst.M_PUSH_NAVTABDATA, menuItem)    this.$store.commit(mainConst.M_UPDATE_NAVTABDATA, {navIndex: navTabData.length - 1})    // 向iframe中的tab添加页签    this.$root.bus.$emit("addIframeTab", iframeTabItem)   },   // 清空导航属性值,确保再次点击无选中样式及不匹配数据   lastmenuChange(menuList, menuItem){    this.funMenu.firstMenu.forEach(function (item) {     item.active = false    })    this.funMenu.nextMenu.forEach(function (item) {     item.active = false    })    this.funMenu.lastMenu.forEach(function (item) {     item.active = false    })    this.funMenu.nextMenu = []    this.funMenu.lastMenu = []   },   // 增加选中样式及赋值下级菜单   getFirstAndNextVal(menuList, menuItem){    var childFuncs = []    for (let i = 0; i < menuList.length; i++) {     if (menuList[i].permissionId == menuItem.permissionId) {      menuList[i].active = true      childFuncs = menuList[i].childFuncs || []     } else {      menuList[i].active = false     }    }    return childFuncs   }  } }</script>

还要添加一个没用的路由,因为我们的锚记还要发生变化

/* * iframe/router/index.js */const systemNamePrefix = "iframe_"import MainContainer from '@/containers/MainContainer.vue'import IframeComponent from '@Iframe/containers/IframeComponent.vue'export default [ {  path: '/iframe',  component: MainContainer,  children: [   {path: ':tag', component: IframeComponent, meta: {requiresAuth: true, keepAlive: true}},  ],  meta: {requiresAuth: true} }]
/* * iframeComponent.vue,一个没用的vue文件,只是为了让浏览器中的锚记发生变化 */<template> <div v-if="isCache">  <span>{{src}}</span> </div></template><style scoped lang="scss"></style><script> export default{  data(){   return {    isCache: true,    src: ''   }  },  created(){  },  mounted(){   // 1、这个页面存在的意义就是在iframe页面切换的时候,路由可以跳转过去用,没有实际大的作用,但是得有这个页面   // 2、iframe的Tab页面的z-index比这个页面的高   this.src=this.$route.params.tag  } }</script>

3. 思考点

虽然这样和iframe结合有点恶心,但是可以实现我们的思路

在这个功能的实现中我们用到了bus事件总线的广播和监听

  1. 其实这点我们是可以仔细思考的,因为大量的使用广播不可控,我们可以完全用vuex去实现,这点用了广播,确实偷懒了
  2. 广播并不是不推荐,而是要使用对场景,这点其实用广播确实不太好,不利于扩展,谁能猜出来会有哪些扩展?

大家不用关心具体的代码,如果你们遇到类似的问题,了解这个思路就可以了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表