当前位置: 移动技术网 > IT编程>脚本编程>vue.js > Vue集成Iframe页面的方法示例

Vue集成Iframe页面的方法示例

2018年02月24日  | 移动技术网IT编程  | 我要评论

sbs演艺大赏2014,重生豪门淑媛,alcatel官网

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. 广播并不是不推荐,而是要使用对场景,这点其实用广播确实不太好,不利于扩展,谁能猜出来会有哪些扩展?

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

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网