08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / project / hivuiMain / components / tabpanel / panel.vue
<template>
    <div class="pl-tabs-panel" :title="title" :style="tabStyle">
        <div class="pl-loading pl-loading-fixed" v-show="url && !loaded" ref="dom-loader">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
        <iframe v-if="hasUrl" @load="handleIframeLoad" :name="'iframe' + name" ref="iframe"></iframe>
        <slot v-if="!hasUrl"></slot>
    </div>
</template>

<script>
import { getUrlValue, setUrlValue, getUrlSearch } from "@main/utils";
import { getToken } from '@main/utils/auth'
export default {
    name: 'PTabpanel',
    props: {
        close: [String, Number, Boolean],
        itemData: Object,
        title: {
            type: String,
            default: ""
        },
        name: {
            type: [String, Number],
            default: ""
        },
        url: {
            type: [String],
            default: ""
        },
        index: [String, Number]
    },
    data() {
        return {
            scrollTop: 0,
            loaded: false,
            loadTimer: null 
        }
    },
    computed: {
        tabStyle() {
            return {
                position: "absolute",
                width: "100%",
                top: this.active ? 0 : "-200%",
                left: 0,
                opacity: this.active ? 1 : 0,
                visibility: this.active ? "visible" : "hidden",
            };
        },
        active() {
            return this.$parent.currentName === this.name;
        },
        //hasUrl改为计算属性,动态监听url变化
        hasUrl() {
            return !(this.url == null || this.url === '');
        }
    },
    watch: {
        active(val) {
            let ifm = this.$refs["iframe"];
            if (val) {
                this.setIframeSrc();
                if (ifm && ifm.contentDocument) {
                    this.$nextTick(() => {
                        //保持原有的滚动位置
                        ifm.contentDocument.documentElement.scrollTop = this.scrollTop;
                    });
                }
            } else {
                if (ifm && ifm.contentDocument) {
                    //保持原有的滚动位置
                    this.scrollTop = ifm.contentDocument.documentElement.scrollTop;
                }
            }
        }
    },
    updated() {
        this.$parent.$emit('tab-nav-update');
    },
    mounted() {
        if (this.active) {
            this.setIframeSrc();
        }
    },
    beforeDestroy() {
        this.clearLoadTimer();
    },
    methods: {
        clearLoadTimer() {
            if (this.loadTimer) {
                clearTimeout(this.loadTimer);
                this.loadTimer = null;
            }
        },
        // 启动加载超时兜底
        startLoadTimer() {
            this.clearLoadTimer();
            this.loadTimer = setTimeout(() => {
                this.loaded = true;
            }, 12000);
        },
        setIframeSrc() {
            let ifm = this.$refs['iframe'];
            if (!this.hasUrl || this.loaded == true) {
                if (ifm && ifm.contentDocument) {
                    ifm.contentWindow.document.body.scrollTop = this.scrollTop;
                }
                return;
            }
            if (ifm && this.url.indexOf("about:blank") < 0) {
                this.loaded = false;
                this.startLoadTimer(); // 开始兜底计时
                ifm.setAttribute('src', this.url);
            } else {
                this.loaded = true;
            }
        },
        reload() {
            let ifm = this.$refs['iframe'];
            this.loaded = false;
            this.startLoadTimer(); // 刷新页面同样开启兜底
            let urlToken = getUrlValue(ifm.contentWindow.location.href, "access_token");
            let nowToken = getToken();
            if (false && !window._global && urlToken && nowToken && (urlToken != nowToken)) {//正式环境
                ifm.contentWindow.location = setUrlValue(decodeURIComponent(ifm.contentWindow.location.href), "access_token", nowToken);
            }
            ifm.contentWindow.location.reload();
        },
        handleIframeLoad(evt) {
            // 正常触发load,清除超时定时器
            this.clearLoadTimer();

            let ifm = this.$refs['iframe'];
            // 尝试获取页面标题,增加try-catch防止跨域报错
            try {
                if (this.title == "" && ifm.contentWindow.document.title != "") {
                    this.$emit("update:title", ifm.contentWindow.document.title);
                }
            } catch (e) {
                // 跨域无法读取标题,静默捕获异常
            }

            // 简化判断,移除危险的contentWindow.body读取(跨域会报错阻断代码)
            if (ifm.src && ifm.src !== "about:blank") {
                this.loaded = true;
            } else {
                this.loaded = true;
            }

            // 绑定beforeunload增加异常捕获
            try {
                if (ifm.contentDocument) {
                    ifm.contentWindow.addEventListener('beforeunload', () => {
                        //this.loaded=false;//右击刷新 时进行加载状态
                    });
                }
            } catch (e) {
            }

            this.loaded && this.$emit('onIframeLoad', this, evt);
        },
    }
}
</script>