Vue集成Iframe页面


声明:本文转载自https://my.oschina.net/u/1416844/blog/1587411,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

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:;" 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:;" :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:;" :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:;">{{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:;">{{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:;" @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事件总线的广播和监听
    • 其实这点我们是可以仔细思考的,因为大量的使用广播不可控,我们可以完全用vuex去实现,这点用了广播,确实偷懒了
    • 广播并不是不推荐,而是要使用对场景,这点其实用广播确实不太好,不利于扩展,谁能猜出来会有哪些扩展?
  • 大家不用关心具体的代码,如果你们遇到类似的问题,了解这个思路就可以了

4. 参考和引用

5. 特别感谢

  • 公司的小伙伴

6. 免责说明

  • 本文档中的部分内容摘自网上的众多博客,仅作为自己知识的补充和整理,并分享给其他需要的coder,不会用于商用。
  • 因为很多博客的地址看完没有及时做保存,所以很多不会在这里标明出处,非常感谢各位大牛的分享,也希望大家理解。
  • 如果原文作者感觉不适,可以及时联系我shiguoqing999@163.com,我将及时删除争议部分内容

7. 追责声明

  • 如有大段引用超过全文50%的内容,请在文档结尾标明原文出处:龙马行空-石国庆-朱庇特-https://my.oschina.net/u/1416844/blog,否则将视为抄袭,予以法律追究,请各位尊重个人知识产权。

本文发表于2017年12月10日 22:37
(c)注:本文转载自https://my.oschina.net/u/1416844/blog/1587411,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2721 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1