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

  import { getViewportOffset } from '/@/utils/domUtils';
V
vben 已提交
14

15
  import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
陈文彬 已提交
16

V
vben 已提交
17 18 19
  import { propTypes } from '/@/utils/propTypes';
  import { useDesign } from '/@/hooks/web/useDesign';

陈文彬 已提交
20 21 22 23
  export default defineComponent({
    name: 'IFrame',
    components: { Spin },
    props: {
V
vben 已提交
24
      frameSrc: propTypes.string.def(''),
陈文彬 已提交
25 26
    },
    setup() {
V
vben 已提交
27
      const loading = ref(false);
陈文彬 已提交
28 29
      const topRef = ref(50);
      const heightRef = ref(window.innerHeight);
V
vben 已提交
30 31 32 33 34 35 36 37 38 39 40 41
      const frameRef = ref<HTMLFrameElement | null>(null);

      const { prefixCls } = useDesign('iframe-page');
      useWindowSizeFn(calcHeight, 150, { immediate: true });

      const getWrapStyle = computed(
        (): CSSProperties => {
          return {
            height: `${unref(heightRef)}px`,
          };
        }
      );
陈文彬 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

      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`;
      }

      function hideLoading() {
V
vben 已提交
57
        loading.value = false;
陈文彬 已提交
58 59 60 61 62 63
        calcHeight();
      }

      function init() {
        nextTick(() => {
          const iframe = unref(frameRef);
V
vben 已提交
64 65 66 67 68
          if (!iframe) return;

          const _frame = iframe as any;
          if (_frame.attachEvent) {
            _frame.attachEvent('onload', () => {
陈文彬 已提交
69 70 71 72 73 74 75 76 77 78
              hideLoading();
            });
          } else {
            iframe.onload = () => {
              hideLoading();
            };
          }
        });
      }
      onMounted(() => {
V
vben 已提交
79
        loading.value = true;
陈文彬 已提交
80 81
        init();
      });
V
vben 已提交
82

陈文彬 已提交
83
      return {
V
vben 已提交
84 85
        getWrapStyle,
        loading,
陈文彬 已提交
86
        frameRef,
V
vben 已提交
87
        prefixCls,
陈文彬 已提交
88 89 90 91 92
      };
    },
  });
</script>
<style lang="less" scoped>
V
vben 已提交
93 94 95
  @prefix-cls: ~'@{namespace}-iframe-page';

  .@{prefix-cls} {
陈文彬 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    .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>