vue+ element 导航菜单加载iframe实现外链内嵌效果

需求如下:

在项目里点击不同的菜单 针对项目内的路由直接在页面上切换路由进行跳转,嵌套的外部链接直接用iframe的url来加载。

部分代码如下:

左侧导航代码示例

 <el-menu  
            :default-active="onRoute"
            class="el-menu-list"
            @open="handleOpen"
            :unique-opened="true"
            @close="handleClose" 
            :collapse="isCollapse">
            <el-submenu :index="item.code" v-for="(item,index) in menuList" :key="index">
                <template slot="title">
                    <i :class="item.icon"></i>
                    <span slot="title">{{item.name}}</span>
                </template>
                <el-menu-item-group>
                    <el-menu-item 
                    @click="handleClick(options)"
                    :index="options.url" v-for="(options,opindex) in item.portalMenuList" :key="opindex">{{options.name}}</el-menu-item>
                </el-menu-item-group>
            </el-submenu>
        </el-menu>
        <!-- 折叠按钮 -->
        <div class="click_btn" v-bind:class="{'unfold_class':isCollapse,'pack_up_class':!isCollapse}" @click="change">
            <img v-bind:class="{'unfold_btn':isCollapse,'pack_up_btn':!isCollapse}" :src="picture + (isCollapse?'/appointment/zhankai.png':'/appointment/shouqi.png')" alt="">
        </div>
        <!-- 折叠按钮end -->

右侧展示路由内容页或者被嵌套的网页 部分代码示例:

 <div class="content-box" :class="{'content-collapse':isCollapse}">
            <div class="content">
                <transition name="move" mode="out-in">
                    <router-view v-show="!showIframe"  ></router-view>
                </transition>
                <transition name="move" mode="out-in">
                    <iframe v-show="showIframe" height="100%" width="100%" :src="iframeUrl" frameborder="0"></iframe>
                </transition>
            </div>
        </div>

计算属性 监听当前导航菜单权限展示默认页面(首页):

 computed:{
        onRoute(){
            let path = '';
            let that = this;
            that.menuList.forEach(item=>{
                if(item.portalMenuList.length>0){
                    item.portalMenuList.forEach(ops=>{
                        if(ops.hasOwnProperty('homePage') && ops.homePage == 'true'){
                            that.showIframe = true;
                            that.iframeUrl = ops.url;
                            path = ops.url
                        }
                    })
                }
            })
            console.log(path)
            return path
        }
    },

监听事件是否有message参数,如果有直接当页面参数获取,方法如下:

receiveMessage(event) {
            let vm = this;
            // For Chrome, the origin property is in the event.originalEvent
            // object.
            // 这里不准确,chrome没有这个属性
            // var origin = event.origin || event.originalEvent.origin;
            var origin = event.origin
            if (origin !== "https://www.xxx.com") {
                return;
            } else {
                if (event.data.officeId) {
                    console.log(event.data.officeId)
                    vm.officeId = event.data.officeId;
                }
                if (event.data.providerId) {
                    vm.personInfoHisId = event.data.providerId
                }
                if (event.data.tenantId) {
                    vm.tenantId = event.data.tenantId;
                }
                this.getListData();
            }
        },
//在mounted 监听
 mounted(){
        window.addEventListener("message", this.receiveMessage, false);
    },
 

获取导航菜单列表方法,并自定义菜单:

// 获取菜单列表
        getListData(){
            let params = {
                officeId: this.officeId,//门店hisid
                tenantId: this.tenantId,//租户ID
                personInfoHisId: this.personInfoHisId,//医生hisId
            }
            this.$post('/getPortalmenu',params,{contentType:'json'}).then(res=>{
                if(res.code == '200'){
                    this.menuList = res.data;
                    this.menuList.forEach(item=>{
                        this.iconList.forEach(ops=>{
                            if(item.code == ops.code){
                                this.$set(item,'icon',ops.icon)
                            }
                        })
                    })
                }
            })
        },
        // 菜单展开
        handleOpen(key, keyPath){
            console.log(key, keyPath);
        },
        // 折叠
        handleClose(key, keyPath){
            console.log('guanb',key, keyPath);
        }


//icon 列表如下所示
iconList:[
                {
                    code:'home',
                    icon:'el-icon-pie-chart'
                },
                {
                    code:'BIll',
                    icon:'el-icon-s-operation'
                },
                {
                    code:'MATERIAL',
                    icon:'el-icon-cloudy'
                },
                {
                    code:'Commission',
                    icon:'el-icon-data-analysis'
                },
                {
                    code:'CRM',
                    icon:'el-icon-s-comment'
                },
                {
                    code:'a1',
                    icon:'el-icon-s-order'
                },
                {
                    code:'a2',
                    icon:'el-icon-folder'
                },
                {
                    code:'a3',
                    icon:'el-icon-s-marketing'
                }
            ],

后台接口返回的json格式如下:

[{
"id":3,
            "isAvailability":1,
            "version":1,
            "name":"核心指标报表",
            "code":"home",
            "parentId":1,
            "url":null,
            "type":1,
            "menuIndex":1,
            "menuType":1,
            "remark":null,
            "portalMenuList":[
                {
                    "id":18,
                    "name":"首页",
                    "code":"homepage",
                    "parentId":3,
                    "url":"https://www.baidu.com",
                    "type":2,
                    "menuIndex":1,
                    "menuType":2,
                    "remark":"首页",
                    "portalMenuList":[{
                    "id":5,
                    "isAvailability":1,
                    "version":1,
                    "name":"数据报表",
                    "code":"BI1",
                    "parentId":2,
                    "url":"https://www.baidu.com",
                    "type":2,
                    "menuIndex":1,
                    "menuType":2,
                    "remark":null,
                    "portalMenuList":null,
                    "officeId":null,
                    "tenantId":null,
                    "personInfoHisId":null,
                    "homePage":null
                },
],
                    "officeId":null,
                    "tenantId":null,
                    "personInfoHisId":null,
                    "homePage":"true"
                }
            ],
            "officeId":null,
            "tenantId":null,
            "personInfoHisId":null,
            "homePage":null
        },
}]

样式部分代码示例:

<style  scoped>
    .etoothMenuMain >>> .el-menu-list:not(.el-menu--collapse) {
        width: 200px;
        height: 100%;
    }
    .etoothMenuMain >>> .el-menu-list{
        margin:10px;
        border:none;
        box-shadow: 1px 3px 5px 3px rgb(221, 218, 218);
    }
    .etoothMenuMain >>> .el-menu-item.is-active{
        background: #409EFF;
        color: #fff;
    }
     /* 折叠按钮样式 */
    .etoothMenuMain .click_btn{
        position: absolute;
        width: 16px;
        height: 52px;
        top: 10px;
        left:-100px;
        z-index: 100;
        -webkit-transition: left .3s ease-in-out;
        transition: left .3s ease-in-out;
    }
    .etoothMenuMain .click_btn img{
        width: 16px;
        height: 52px;
    }
    .etoothMenuMain .unfold_class{
        left: 74px;
    }
    .etoothMenuMain .pack_up_class{
        left: 210px;
    }
    .etoothMenuMain >>> .content-box{
        position: absolute;
        top:0;
        background: #fff;
    }
    .etoothMenuMain >>> .content-collapse{
        left: 91px;
    }
</style>

 

以上即可

 新增知识点:

当被嵌套页面有媒体权限时,iframe 也要增加属性 allow

 <transition name="move" mode="out-in">
                    <iframe 
                        height="100%" 
                        width="100%"
                        v-show="showIframe"
                        :src="iframeUrl" 
                        frameborder="0" 
                        ref="lookLive"></iframe>
                </transition>
 mounted(){
        let vm = this;
        window.addEventListener("message", this.receiveMessage, false);
        // vm.officeId = vm.$route.query.officeId; 
        // vm.personInfoHisId = vm.$route.query.personInfoHisId;
        // vm.tenantId = vm.$route.query.tenantId;
        // this.getListData();
        this.$nextTick(()=>{
            var iframeElment = this.$refs.lookLive;
            if (iframeElment) {
                console.log(iframeElment,'111')
                iframeElment.allow = 'camera;microphone;'
            }
        })
    },

 

posted @ 2021-12-14 14:34  巫小婆  阅读(3531)  评论(0编辑  收藏  举报