PreviewOnline.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <template>
  2. <div class="preview-online-container" v-if="showPreviewOnline">
  3. <el-icon class="close-icon" @click="close"><CloseBold /></el-icon>
  4. <component
  5. v-if="dynamicComponent[documentType as keyof typeof dynamicComponent]"
  6. :is="dynamicComponent[documentType as keyof typeof dynamicComponent]"
  7. :src="documentUrl"
  8. />
  9. <template v-else>
  10. <div class="preview-img">
  11. <img :alt="documentUrl" :src="documentUrl" />
  12. </div>
  13. </template>
  14. </div>
  15. </template>
  16. <script lang="ts" setup>
  17. import { ref, computed, defineAsyncComponent } from 'vue';
  18. import { CloseBold } from '@element-plus/icons-vue';
  19. import { FILE_TYPE_ICON } from '@/components/UploadFiles/constants';
  20. import '@vue-office/docx/lib/index.css';
  21. import '@vue-office/excel/lib/index.css';
  22. const showPreviewOnline = ref(false);
  23. const documentUrl = ref('');
  24. const documentType = ref<keyof typeof FILE_TYPE_ICON>();
  25. const open = (url: string, type: keyof typeof FILE_TYPE_ICON) => {
  26. showPreviewOnline.value = true;
  27. documentUrl.value = url;
  28. documentType.value = type;
  29. };
  30. const close = () => {
  31. showPreviewOnline.value = false;
  32. };
  33. const dynamicComponent = computed(() => {
  34. return {
  35. word: defineAsyncComponent(() => import('@vue-office/docx')),
  36. excel: defineAsyncComponent(() => import('@vue-office/excel')),
  37. pdf: defineAsyncComponent(() => import('@vue-office/pdf')),
  38. ppt: defineAsyncComponent(() => import('@vue-office/pptx')),
  39. };
  40. });
  41. defineExpose({
  42. open,
  43. });
  44. </script>
  45. <style lang="scss" scoped>
  46. .preview-online-container {
  47. position: fixed;
  48. top: 0;
  49. left: 0;
  50. width: 100vw;
  51. height: 100vh;
  52. background-color: rgba(0, 0, 0, 0.3);
  53. z-index: 9999;
  54. }
  55. .close-icon {
  56. position: absolute;
  57. top: 20px;
  58. right: 20px;
  59. cursor: pointer;
  60. font-size: 30px;
  61. color: $text-color;
  62. z-index: 9999;
  63. }
  64. .preview-img {
  65. position: fixed;
  66. top: 0;
  67. left: 0;
  68. width: 100vw;
  69. height: 100vh;
  70. background-color: rgba(0, 0, 0, 0.3);
  71. z-index: 9998;
  72. display: flex;
  73. justify-content: center;
  74. align-items: center;
  75. }
  76. :deep(.docx-wrapper) {
  77. background: $white-color;
  78. padding: 0;
  79. }
  80. :deep(.slide-master-wrapper) {
  81. height: 100vh;
  82. }
  83. :deep(.vue-office-pdf) {
  84. height: 100% !important;
  85. overflow-y: auto !important;
  86. }
  87. :deep(.vue-office-pptx) {
  88. height: 100vh !important;
  89. overflow-y: auto !important;
  90. }
  91. :deep(.pptx-preview-wrapper) {
  92. height: 100% !important;
  93. overflow-y: auto !important;
  94. }
  95. </style>