index.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <template>
  2. <div class="iframe-page" :style="getWrapStyle">
  3. <Spin :spinning="loading" size="large" :style="getWrapStyle">
  4. <iframe :src="frameSrc" class="iframe-page__main" ref="frameRef" />
  5. </Spin>
  6. </div>
  7. </template>
  8. <script lang="ts">
  9. import { defineComponent, PropType, ref, unref, onMounted, nextTick, computed } from 'vue';
  10. import { Spin } from 'ant-design-vue';
  11. import { getViewportOffset } from '/@/utils/domUtils';
  12. import { useWindowSizeFn } from '/@/hooks/event/useWindowSize';
  13. export default defineComponent({
  14. name: 'IFrame',
  15. components: { Spin },
  16. props: {
  17. frameSrc: {
  18. type: String as PropType<string>,
  19. },
  20. },
  21. setup() {
  22. const loadingRef = ref(false);
  23. const topRef = ref(50);
  24. const heightRef = ref(window.innerHeight);
  25. const frameRef = ref<HTMLElement | null>(null);
  26. function calcHeight() {
  27. const iframe = unref(frameRef);
  28. if (!iframe) {
  29. return;
  30. }
  31. let { top } = getViewportOffset(iframe);
  32. top += 20;
  33. topRef.value = top;
  34. heightRef.value = window.innerHeight - top;
  35. const clientHeight = document.documentElement.clientHeight - top;
  36. iframe.style.height = `${clientHeight}px`;
  37. }
  38. useWindowSizeFn(calcHeight, 150, { immediate: true });
  39. function hideLoading() {
  40. loadingRef.value = false;
  41. calcHeight();
  42. }
  43. function init() {
  44. nextTick(() => {
  45. const iframe = unref(frameRef);
  46. if (!iframe) {
  47. return;
  48. }
  49. if ((iframe as any).attachEvent) {
  50. (iframe as any).attachEvent('onload', () => {
  51. hideLoading();
  52. });
  53. } else {
  54. iframe.onload = () => {
  55. hideLoading();
  56. };
  57. }
  58. });
  59. }
  60. onMounted(() => {
  61. loadingRef.value = true;
  62. init();
  63. });
  64. return {
  65. getWrapStyle: computed(() => {
  66. return {
  67. height: `${unref(heightRef)}px`,
  68. };
  69. }),
  70. loading: loadingRef,
  71. frameRef,
  72. };
  73. },
  74. });
  75. </script>
  76. <style lang="less" scoped>
  77. .iframe-page {
  78. .ant-spin-nested-loading {
  79. position: relative;
  80. height: 100%;
  81. .ant-spin-container {
  82. width: 100%;
  83. height: 100%;
  84. padding: 10px;
  85. }
  86. }
  87. &__mask {
  88. position: absolute;
  89. top: 0;
  90. left: 0;
  91. width: 100%;
  92. height: 100%;
  93. }
  94. &__main {
  95. width: 100%;
  96. height: 100%;
  97. overflow: hidden;
  98. background: #fff;
  99. border: 0;
  100. box-sizing: border-box;
  101. }
  102. }
  103. </style>