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
// 一、監聽添加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)
})
// 二、監聽切換iframe中tab的廣播
this.$root.bus.$on('changeIframeTab', function (tag) {
_this.$store.commit(mainConst.M_IFRAME_CHANGE_SELECTCODE, tag)
})
// 三、監聽刪除iframe中tab的廣播
this.$root.bus.$on('deleteIframeTab', function (obj) {
// 一、刪除iframe中的指定tab頁面
_this.$store.commit(mainConst.M_IFRAME_DELETE_TAB, obj)
// _this.tabsList = _this.tabsList.filter(tab => tab.tag !== obj.tag)
// 二、若是刪除的一級tab不是當前激活的一級tab,TabsTemeplate中的一級tab刪除事件已經在vuex中刪除了,不須要作路由跳轉操做了
let index = obj.index
for (let i = 0; i < _this.navTabData.length; i++) {
if (_this.navTabData[i].active) {
return
}
}
// 三、若是刪除的一級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 = {}
// 一、路由跳轉和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}})
}
// 二、判斷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
}
}
// 三、向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(){
// 一、這個頁面存在的意義就是在iframe頁面切換的時候,路由能夠跳轉過去用,沒有實際大的做用,可是得有這個頁面
// 二、iframe的Tab頁面的z-index比這個頁面的高
this.src=this.$route.params.tag
}
}
</script>
3. 思考點
- 雖然這樣和iframe結合有點噁心,可是能夠實現咱們的思路
- 在這個功能的實現中咱們用到了bus事件總線的廣播和監聽
- 其實這點咱們是能夠仔細思考的,由於大量的使用廣播不可控,咱們能夠徹底用vuex去實現,這點用了廣播,確實偷懶了
- 廣播並非不推薦,而是要使用對場景,這點其實用廣播確實不太好,不利於擴展,誰能猜出來會有哪些擴展?
- 你們不用關心具體的代碼,若是大家遇到相似的問題,瞭解這個思路就能夠了
4. 參考和引用
5. 特別感謝
6. 免責說明
- 本文檔中的部份內容摘自網上的衆多博客,僅做爲本身知識的補充和整理,並分享給其餘須要的coder,不會用於商用。
- 由於不少博客的地址看完沒有及時作保存,因此不少不會在這裏標明出處,很是感謝各位大牛的分享,也但願你們理解。
- 若是原文做者感受不適,能夠及時聯繫我shiguoqing999@163.com,我將及時刪除爭議部份內容
7. 追責聲明