frame.vue 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <script setup lang="ts">
  2. import { useI18n } from "vue-i18n";
  3. import { useRoute } from "vue-router";
  4. import { ref, unref, watch, onMounted, nextTick } from "vue";
  5. defineOptions({
  6. name: "LayFrame"
  7. });
  8. const props = defineProps<{
  9. frameInfo?: {
  10. frameSrc?: string;
  11. fullPath?: string;
  12. };
  13. }>();
  14. const { t } = useI18n();
  15. const loading = ref(true);
  16. const currentRoute = useRoute();
  17. const frameSrc = ref<string>("");
  18. const frameRef = ref<HTMLElement | null>(null);
  19. if (unref(currentRoute.meta)?.frameSrc) {
  20. frameSrc.value = unref(currentRoute.meta)?.frameSrc as string;
  21. }
  22. unref(currentRoute.meta)?.frameLoading === false && hideLoading();
  23. function hideLoading() {
  24. loading.value = false;
  25. }
  26. function init() {
  27. nextTick(() => {
  28. const iframe = unref(frameRef);
  29. if (!iframe) return;
  30. const _frame = iframe as any;
  31. if (_frame.attachEvent) {
  32. _frame.attachEvent("onload", () => {
  33. hideLoading();
  34. });
  35. } else {
  36. iframe.onload = () => {
  37. hideLoading();
  38. };
  39. }
  40. });
  41. }
  42. watch(
  43. () => currentRoute.fullPath,
  44. path => {
  45. if (
  46. currentRoute.name === "Redirect" &&
  47. path.includes(props.frameInfo?.fullPath)
  48. ) {
  49. frameSrc.value = path; // redirect时,置换成任意值,待重定向后 重新赋值
  50. loading.value = true;
  51. }
  52. // 重新赋值
  53. if (props.frameInfo?.fullPath === path) {
  54. frameSrc.value = props.frameInfo?.frameSrc;
  55. }
  56. }
  57. );
  58. onMounted(() => {
  59. init();
  60. });
  61. </script>
  62. <template>
  63. <div
  64. v-loading="loading"
  65. class="frame"
  66. :element-loading-text="t('status.pureLoad')"
  67. >
  68. <iframe ref="frameRef" :src="frameSrc" class="frame-iframe" />
  69. </div>
  70. </template>
  71. <style lang="scss" scoped>
  72. .frame {
  73. position: absolute;
  74. inset: 0;
  75. .frame-iframe {
  76. box-sizing: border-box;
  77. width: 100%;
  78. height: 100%;
  79. overflow: hidden;
  80. border: 0;
  81. }
  82. }
  83. .main-content {
  84. margin: 2px 0 0 !important;
  85. }
  86. </style>