2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1. 项目需求

  • 我们切换为vue框架是后面的事情,之前还有一些功能页面是用jsp页面写的,而我们的管理系统需要既支持Vue的url,又要支持这些发布之后的jsp页面
  • 还有一个就是切换tab回来的时候之前输入的东西还要存在
  • 系统页面截图

104643_M5wr_1416844.jpg

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"><TabPanev-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=>iframeTabDataimport {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.indexfor (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.urlcon.active = true// 如果还有其他一级的tab,那么还要判断跳转的页面是不是iframeif (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事件广播实现的

104643_jedX_1416844.jpg

/** 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.navIndexstate.navTabData.forEach((item)=> {item.active = false})// 当你利用索引直接设置一个项时是不能触发视图的从新渲染的,下面是老方法和解决办法// state.navTabData[index].active=truelet 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"><liv-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(){// 跳转首页就关闭iframethis.$store.commit(mainConst.M_HIDE_IFRAME)this.$router.push(`/${this.$store.state.systemName}`)},// ★★★★★调用方法获取三级菜单列表★★★★★getMainMenu(){var _this = thisif (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 = []}breakcase "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)}breakcase "lastMenu": {this.clickMenuJump(menuList, menuItem)}break}},// ★★★★★点击有url的菜单,跳转事件★★★★★clickMenuJump(menuList, menuItem){if (!menuItem.url.length) returnthis.funMenu.menuIsShow = falsethis.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.urllet userId = storage.getItem('hivescm.userAuthor').idlet token = storage.getItem('hivescm.userAuthor').tokeniframeTabItem.url = `${menuItem.url}?userId=${userId}&token=${token}`} else {let userId = storage.getItem('hivescm.userAuthor').idlet token = storage.getItem('hivescm.userAuthor').tokeniframeTabItem.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,隐藏iframethis.$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.navTabDatafor (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 = truechildFuncs = menuList[i].childFuncs || []} else {menuList[i].active = false}}return childFuncs}}}
</script>
  • 还要添加一个没用的路由,因为我们的锚记还要发生变化

104643_N6Zj_1416844.jpg

/** 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,否则将视为抄袭,予以法律追究,请各位尊重个人知识产权。

转载于:https://my.oschina.net/u/1416844/blog/1587411

Vue集成Iframe页面相关推荐

  1. 了解一下iframe页面嵌入使用,轻松实现页面集成

    前言 在跨域请求不同服务方或是兼容先前系统的页面时,你可能想利用AJAX从网页上下载HTML并粘贴到div中,这将带来不安全注入的问题. 此时,通过iframe页面嵌入可以很好地解决上述问题. 本文带 ...

  2. vue 中嵌入iframe页面

    使用的是vue-element-admin. 需求 项目需求是在点击左边侧边栏的时候判断如果是外部的页面之后,将此页面在右侧打开,每打开一个,tagview中也会相应加上,当切换这些tagview时, ...

  3. vue中用iframe嵌套页面,点击返回实现真正的退回上一步功能

    vue项目中需要嵌套第三方的页面,但是第三方页面中的网页没有返回按钮,如图所示:此为页面b,页面a为跳到b页面的前一个页面. 点击iframe嵌套页面跳转的第二个页面 要实现不管进入多少层iframe ...

  4. Node.js、Npm、MVVM模式、idea的vue集成

    Node.js 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js是一个事件驱动 ...

  5. 如何使用Vue集成其它UI组件?如何阅读UI官网?移动端组件Vant实例教程(熬夜干货)

    如何使用Vue集成其它UI组件 前言 一.Vant是什么? 二.基础环境准备 1.1 了解是根本 1.2 安装 1.3 引入组件 3.1 步骤一 3.2 步骤二 3.3 步骤三 二.事件绑定 2.1 ...

  6. SpreadJS与Vue集成,苏宁集团『极客办公』系统开发案例

    "造极"如今已成为苏宁集团的年度核心关键词."造极"在具体工作上的体现,代表着苏宁不断追求极致的工匠精神,即对待每一个环节,都要严格要求.精益求精." ...

  7. vue用iframe播放海康视频

    由于项目需要同时显示两个相机的视频,使用上一篇文章封装的组件无法完成,因为当时webVideoCtrl.js是直接定义在全局的,$相当于一整个项目的window,无论怎么使用都只能在第一次定义的dom ...

  8. vue集成Highcharts 云词图

    vue集成Highcharts 云词图 最近接手一个需求,需要服务端统计词语,前端出一个云图. 记得很早之前在echarts看到过一个云词图,去翻一下echarts官网没翻到索性去Highcharts ...

  9. vue集成超图supermap-cesium实践

    一.使用vue-cli创建vue工程 1,cmd进入文件夹20200305,创建名为vuesupermap的工程. 命令为:vue init webpack vuesupermap 2,进入项目根目录 ...

最新文章

  1. 定档12月22日!《黑客帝国4》王者归来,再掀矩阵革命
  2. ASP.NET Core微服务(七)——【docker部署linux上线】(RDS+API接口测试部分)
  3. LeetCode 02.两数相加
  4. 为GridView-Delete列添加确认对话框(2种方法)
  5. java statement 动态参数_java_web学习(九) PreparedStatement动态参数的引入
  6. easyui快速入门
  7. python编写程序输出诗句_python基于词向量的古诗生成器
  8. 打印日志文件并将其上传存到HDFS中
  9. 这15个PDF转化工具
  10. HFDS 常用命令 fsck 查看文件信息和block位置信息
  11. Linux安装与卸载Nginx
  12. Android聊天软件的开发(七)--聊天通信
  13. python网页登录钉钉_关于钉钉接口使用Python,Post 500报错
  14. 函数定义与调用,自己实现pow()函数对整数的运算
  15. php人事考勤系统,基于PHPMySQL的考勤系统
  16. java 时间表达式_【JAVA】Quartz中时间表达式的设置
  17. 图片点击放大,并显示浮层
  18. 一文读懂哈希时间锁的合约机制、改进方向与应用场景
  19. 计算机图形学:传统函数方法判定点在不规则封闭区域内的判定方法
  20. 从“数学归纳法”到理解

热门文章

  1. 不同分类算法的优缺点是什么?(值得推荐)
  2. 搜集了一些模型,精模低模都有
  3. 评审关上了你CVPR的门?这还有Rebuttal的窗,7个小技巧送上
  4. 苹果汽车高管几乎流失殆尽,一年损失7人,新年又有人被Meta挖走
  5. 60%收入来自海外,VC追着投资,这匹千里马如此回答“AI往何处去”
  6. 咱们程序员,能吵吵就别动手!现在靠说就可以编程,支持Java、Python等10种语言|免费...
  7. 比英伟达便宜4000元、功耗更低、游戏性能相同,AMD发布RX 6900 XT旗舰显卡
  8. 1种策略就能控制多类模型,华人大二学生提出RL泛化方法,LeCun认可转发 | ICML 2020...
  9. ssm中shiro的使用
  10. STM32F103--(二) GPIO实践