溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue如何集成Iframe頁(yè)面

發(fā)布時(shí)間:2021-07-20 11:41:09 來(lái)源:億速云 閱讀:298 作者:小新 欄目:web開發(fā)

這篇文章主要為大家展示了“Vue如何集成Iframe頁(yè)面”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Vue如何集成Iframe頁(yè)面”這篇文章吧。

1. 項(xiàng)目需求

我們切換為vue框架是后面的事情,之前還有一些功能頁(yè)面是用jsp頁(yè)面寫的,而我們的管理系統(tǒng)需要既支持Vue的url,又要支持這些發(fā)布之后的jsp頁(yè)面

還有一個(gè)就是切換tab回來(lái)的時(shí)候之前輸入的東西還要存在

系統(tǒng)頁(yè)面截圖

Vue如何集成Iframe頁(yè)面

2. 實(shí)現(xiàn)思路

針對(duì)這個(gè)問(wèn)題,我們最開始的實(shí)現(xiàn)思路是寫了一個(gè)iframe的通用組件,然后把不同的http的頁(yè)面的url傳遞進(jìn)來(lái)進(jìn)行切換,但是這樣不滿足第二條,我們發(fā)現(xiàn)只要切換了vue的路由,然后再切回http的頁(yè)面,iframe中的src屬性的頁(yè)面就會(huì)從新刷新,沒(méi)有辦法保留住東西,于是就有了下面的實(shí)現(xiàn)思路

我們?cè)趘ue的router-view同級(jí)別添加了一個(gè)iframeTemp組件,其實(shí)就是一個(gè)elementUI的tab組件,然后把tab組件的頭的樣式隱藏在我們菜單欄的下面

<template>
 <!--路由渲染的功能模塊區(qū)域-->
 <div class="router-out-content">
  <!--緩存部分頁(yè)面的寫法-->
  <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>
  <!--兼容系統(tǒng)外部頁(yè)面-->
  <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組件的內(nèi)部
 **/

 <template>
 <!--iframe頁(yè)面展示區(qū)域-->
 <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 {
  /*測(cè)試位置的時(shí)候顯示這段--開始*/
  /*width: 100%;*/
  /*height: 100%;*/
  /*background-color: red;*/
  /*display: block !important;*/
  /*測(cè)試位置的時(shí)候顯示這段--結(jié)束*/
  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、監(jiān)聽添加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、監(jiān)聽切換iframe中tab的廣播
   this.$root.bus.$on('changeIframeTab', function (tag) {
    _this.$store.commit(mainConst.M_IFRAME_CHANGE_SELECTCODE, tag)

   })
   // 3、監(jiān)聽刪除iframe中tab的廣播
   this.$root.bus.$on('deleteIframeTab', function (obj) {
    // 1、刪除iframe中的指定tab頁(yè)面
    _this.$store.commit(mainConst.M_IFRAME_DELETE_TAB, obj)
    // _this.tabsList = _this.tabsList.filter(tab => tab.tag !== obj.tag)

    // 2、如果刪除的一級(jí)tab不是當(dāng)前激活的一級(jí)tab,TabsTemeplate中的一級(jí)tab刪除事件已經(jīng)在vuex中刪除了,不需要做路由跳轉(zhuǎn)操作了
    let index = obj.index
    for (let i = 0; i < _this.navTabData.length; i++) {
     if (_this.navTabData[i].active) {
      return
     }
    }

    // 3、如果刪除的一級(jí)tab是當(dāng)前激活的一級(jí)tab,
    const con = _this.navTabData[index - 1] || _this.navTabData[index]
    let url = `/${_this.systemName}`
    if (con) {
     // 還有其他的一級(jí)tab,就賦值其他的一級(jí)tab的url,探后跳轉(zhuǎn)
     url = con.url
     con.active = true

     // 如果還有其他一級(jí)的tab,那么還要判斷跳轉(zhuǎn)的頁(yè)面是不是iframe
     if (url.toLowerCase().indexOf("/iframe") == 0) {
      // 如果是iframe頁(yè)面,顯示iframe,廣播iframe的切換tab切換事件,路由進(jìn)行跳轉(zhuǎn)
      _this.$store.commit(mainConst.M_SHOW_IFRAME)
      _this.$root.bus.$emit("changeIframeTab", url.slice(8))

     } else {
      // 如果不是iframe頁(yè)面,隱藏iframe,路由進(jìn)行跳轉(zhuǎn)
      _this.$store.commit(mainConst.M_HIDE_IFRAME)
      // _this.$store.commit(mainConst.M_UPDATE_NAVTABDATA, {navIndex: index})
     }
    }
    else {
     // 沒(méi)有其他的一級(jí)tab,直接隱藏iframe,跳首頁(yè)
     _this.$store.commit(mainConst.M_HIDE_IFRAME)
    }

    _this.$router.push(url)
   })
  }
 }
</script>

之后的ifram組件的顯示隱藏和tab切換,都是通用vuex和bus事件廣播實(shí)現(xiàn)的

Vue如何集成Iframe頁(yè)面

/*
 * mainConst.js
 **/


/*****************************getter常量****************************************/
export const G_GET_NAVTABDATA = 'G_GET_NAVTABDATA'

/*****************************mutations常量*************************************/
// 一級(jí)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'

// 設(shè)置全局系統(tǒng)變量
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: {
  // 一級(jí)Tab導(dǎo)航數(shù)據(jù)集合
  navTabData: [],
  // 進(jìn)入的主系統(tǒng)前綴
  systemName:'',
  // 控制路由同級(jí)的Iframe的顯示隱藏
  showIframe: false,
  // iframe頁(yè)面中的選中頁(yè)簽的code值
  iframeSelectTab:'',
  // iframe頁(yè)面的tab數(shù)據(jù)集合
  iframeTabData:[]

 },
 getters: {
  [mainConst.G_GET_NAVTABDATA](state, getters){
   return state.navTabData
  }
 },
 mutations: {
  // 一級(jí)tab處理
  [mainConst.M_UPDATE_NAVTABDATA](state, payload){
   const index = payload.navIndex
   state.navTabData.forEach((item)=> {
    item.active = false
   })

   // 當(dāng)你利用索引直接設(shè)置一個(gè)項(xiàng)時(shí)是不能觸發(fā)視圖的從新渲染的,下面是老方法和解決辦法
   // 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
  },
  // 設(shè)置全局system變量
  [mainConst.M_SET_SYSTEMNAME] (state, payload) {
   state.systemName=payload
  }
 },
 actions: {
  // actions的最終功能是修改state,但是它不直接修改state,而是調(diào)用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,而是調(diào)用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)
  // }
 }
}
/*
 * 三級(jí)菜單的點(diǎn)擊處理
 **/
<template>
 <!--三級(jí)菜單導(dǎo)航功能-->
 <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">功能導(dǎo)航</a>
     <div class="more-menu clearfix" v-show="funMenu.firstMenu.length&&funMenu.menuIsShow">
      <!--一級(jí)導(dǎo)航-->
      <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>
      <!--二級(jí)導(dǎo)航-->
      <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>
      <!--三級(jí)導(dǎo)航-->
      <!--存在四級(jí)導(dǎo)航-->
      <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>
        <!--三級(jí)導(dǎo)航可點(diǎn)擊-->
        <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">首頁(yè)</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">首頁(yè)</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: {
     // 一級(jí)菜單
     firstMenu: [],
     // 二級(jí)菜單
     nextMenu: [],
     // 三級(jí)菜單
     lastMenu: [],
     // 是否顯示
     menuIsShow: true
    }
   }
  },
  computed: mapState({
   // 箭頭函數(shù)可使代碼更簡(jiǎn)練
   funcMenuList: state => state.funcMenuList,
  }),
  methods: {
   // 跳轉(zhuǎn)首頁(yè)
   goHome(){
    // 跳轉(zhuǎn)首頁(yè)就關(guān)閉iframe
    this.$store.commit(mainConst.M_HIDE_IFRAME)
    this.$router.push(`/${this.$store.state.systemName}`)
   },
   // ★★★★★調(diào)用方法獲取三級(jí)菜單列表★★★★★
   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
       })
     }
    }
   },
   // 點(diǎn)擊菜單展開下一級(jí)別列表事件
   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
    }
   },
   // ★★★★★點(diǎn)擊有url的菜單,跳轉(zhuǎn)事件★★★★★
   clickMenuJump(menuList, menuItem){
    if (!menuItem.url.length) return
    this.funMenu.menuIsShow = false
    this.lastmenuChange(menuList, menuItem)
    let iframeTabItem = {}
    // 1、路由跳轉(zhuǎn)和iframe的顯示隱藏
    if (menuItem.url.toLowerCase().indexOf("/") != 0 || menuItem.url.toLowerCase().indexOf("/iframe") == 0) {
     // 判斷如果是iframe的url,顯示iframe
     // 定義一個(gè)新的item對(duì)象,防止對(duì)象的引用
     iframeTabItem = Object.assign({}, menuItem)
     this.$store.commit(mainConst.M_SHOW_IFRAME)
     // 待優(yōu)化:應(yīng)該有優(yōu)化為手動(dòng)賦值樣式
     // (1)、此處利用router-view的特性,讓一級(jí)tab變顏色
     // (2)、這個(gè)還是控制一級(jí)tab點(diǎn)擊切換tab標(biāo)簽的重要因素
     // 因?yàn)樵嫉膇frame的url已經(jīng)改變,所以要保存到一個(gè)新的變量里面,如果已經(jīng)有了就不需要在放了
     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中是否有重復(fù)的tab標(biāo)簽
    let navTabData = this.$store.state.navTabData
    for (let i = 0; i < navTabData.length; i++) {
     if (navTabData[i].url == menuItem.url) {
      // 已經(jīng)有頁(yè)簽了,一級(jí)tab內(nèi)容不重新渲染
      // 切換一級(jí)tab頁(yè)簽的激活樣式
      this.$store.commit(mainConst.M_UPDATE_NAVTABDATA, {navIndex: i})
      // 從新計(jì)算一級(jí)tab位置
      this.$root.bus.$emit("clickLastMenu", menuItem)

      if (menuItem.url.toLowerCase().indexOf("/iframe") == 0) {
       // 如果已經(jīng)iframe中的tab已經(jīng)存在,那么觸發(fā)iframe中的切換事件
//       this.$store.commit(mainConst.M_SHOW_IFRAME)
       this.$root.bus.$emit("changeIframeTab", menuItem.url.slice(8))
      }
      return
     }
    }

    // 3、向vuex中添加一級(jí)tab
    // 默認(rèn)是否選中
    menuItem.active = true
    // 向一級(jí)tab中添加新的tab標(biāo)簽
    this.$store.commit(mainConst.M_PUSH_NAVTABDATA, menuItem)
    this.$store.commit(mainConst.M_UPDATE_NAVTABDATA, {navIndex: navTabData.length - 1})
    // 向iframe中的tab添加頁(yè)簽
    this.$root.bus.$emit("addIframeTab", iframeTabItem)
   },
   // 清空導(dǎo)航屬性值,確保再次點(diǎn)擊無(wú)選中樣式及不匹配數(shù)據(jù)
   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 = []
   },
   // 增加選中樣式及賦值下級(jí)菜單
   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>

還要添加一個(gè)沒(méi)用的路由,因?yàn)槲覀兊腻^記還要發(fā)生變化

Vue如何集成Iframe頁(yè)面

/*
 * 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,一個(gè)沒(méi)用的vue文件,只是為了讓瀏覽器中的錨記發(fā)生變化
 */

<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、這個(gè)頁(yè)面存在的意義就是在iframe頁(yè)面切換的時(shí)候,路由可以跳轉(zhuǎn)過(guò)去用,沒(méi)有實(shí)際大的作用,但是得有這個(gè)頁(yè)面
   // 2、iframe的Tab頁(yè)面的z-index比這個(gè)頁(yè)面的高
   this.src=this.$route.params.tag
  }
 }
</script>

3. 思考點(diǎn)

雖然這樣和iframe結(jié)合有點(diǎn)惡心,但是可以實(shí)現(xiàn)我們的思路

在這個(gè)功能的實(shí)現(xiàn)中我們用到了bus事件總線的廣播和監(jiān)聽

  1. 其實(shí)這點(diǎn)我們是可以仔細(xì)思考的,因?yàn)榇罅康氖褂脧V播不可控,我們可以完全用vuex去實(shí)現(xiàn),這點(diǎn)用了廣播,確實(shí)偷懶了

  2. 廣播并不是不推薦,而是要使用對(duì)場(chǎng)景,這點(diǎn)其實(shí)用廣播確實(shí)不太好,不利于擴(kuò)展,誰(shuí)能猜出來(lái)會(huì)有哪些擴(kuò)展?

以上是“Vue如何集成Iframe頁(yè)面”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI