index.vue 2.6 KB
Newer Older
陈文彬 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
<template>
  <div class="iframe-page" :style="getWrapStyle">
    <Spin :spinning="loading" size="large" :style="getWrapStyle">
      <iframe :src="frameSrc" class="iframe-page__main" ref="frameRef" />
    </Spin>
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType, ref, unref, onMounted, nextTick, computed } from 'vue';
  import { Spin } from 'ant-design-vue';

  import { getViewportOffset } from '/@/utils/domUtils';
  import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
陈文彬 已提交
14

陈文彬 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  export default defineComponent({
    name: 'IFrame',
    components: { Spin },
    props: {
      frameSrc: {
        type: String as PropType<string>,
      },
    },
    setup() {
      const loadingRef = ref(false);
      const topRef = ref(50);
      const heightRef = ref(window.innerHeight);
      const frameRef = ref<HTMLElement | null>(null);

      function calcHeight() {
        const iframe = unref(frameRef);
        if (!iframe) {
          return;
        }
        let { top } = getViewportOffset(iframe);
        top += 20;
        topRef.value = top;
        heightRef.value = window.innerHeight - top;
        const clientHeight = document.documentElement.clientHeight - top;
        iframe.style.height = `${clientHeight}px`;
      }

      useWindowSizeFn(calcHeight, 150, { immediate: true });

      function hideLoading() {
        loadingRef.value = false;
        calcHeight();
      }

      function init() {
        nextTick(() => {
          const iframe = unref(frameRef);
          if (!iframe) {
            return;
          }
          if ((iframe as any).attachEvent) {
            (iframe as any).attachEvent('onload', () => {
              hideLoading();
            });
          } else {
            iframe.onload = () => {
              hideLoading();
            };
          }
        });
      }
      onMounted(() => {
        loadingRef.value = true;
        init();
      });
      return {
        getWrapStyle: computed(() => {
          return {
            height: `${unref(heightRef)}px`,
          };
        }),
        loading: loadingRef,
        frameRef,
      };
    },
  });
</script>
<style lang="less" scoped>
  .iframe-page {
    .ant-spin-nested-loading {
      position: relative;
      height: 100%;

      .ant-spin-container {
        width: 100%;
        height: 100%;
        padding: 10px;
      }
    }

    &__mask {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }

    &__main {
      width: 100%;
      height: 100%;
      overflow: hidden;
      background: #fff;
      border: 0;
      box-sizing: border-box;
    }
  }
</style>