index.vue 2.9 KB

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