Vue集成Iframe页面的方法示例
程序员文章站
2022-07-09 18:39:28
1. 项目需求
我们切换为vue框架是后面的事情,之前还有一些功能页面是用jsp页面写的,而我们的管理系统需要既支持vue的url,又要支持这些发布之后的jsp页面...
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事件总线的广播和监听
- 其实这点我们是可以仔细思考的,因为大量的使用广播不可控,我们可以完全用vuex去实现,这点用了广播,确实偷懒了
- 广播并不是不推荐,而是要使用对场景,这点其实用广播确实不太好,不利于扩展,谁能猜出来会有哪些扩展?
大家不用关心具体的代码,如果你们遇到类似的问题,了解这个思路就可以了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: Windows下Python的安装