VbImagePreview.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <script setup lang="ts">
  2. import Rs from "@@/services/RequestService"
  3. const props = withDefaults(
  4. defineProps<{
  5. src: string
  6. prefixSrc?: string
  7. fit?: "" | "fill" | "none" | "contain" | "cover" | "scale-down"
  8. width?: string | number
  9. height?: string | number
  10. imageStyle?: any
  11. url?: string
  12. load?: (e: any) => void
  13. error?: (e: any) => void
  14. }>(),
  15. {
  16. width: 75,
  17. height: 50,
  18. prefixSrc: "/resource/oss/preview/",
  19. url: "/resource/oss/preview/",
  20. fit: "cover",
  21. imageStyle: () => {
  22. return {
  23. margin: "0 5px"
  24. }
  25. }
  26. }
  27. )
  28. function formatUrl(url: string) {
  29. if (isExternal(url)) {
  30. return url
  31. }
  32. url = import.meta.env.VITE_APP_BASE_API + (props.prefixSrc ? props.prefixSrc : "") + url
  33. return url
  34. }
  35. const srcList = ref<any>([])
  36. const imgStyle = computed(() => {
  37. const style = typeof props.imageStyle == "object" ? props.imageStyle : {}
  38. if (!style.width) {
  39. style.width = typeof props.width == "string" ? props.width : `${props.width}px`
  40. }
  41. if (!style.height) {
  42. style.height = typeof props.height == "string" ? props.height : `${props.height}px`
  43. }
  44. return style
  45. })
  46. function load() {
  47. srcList.value = []
  48. if (!props.src) {
  49. return
  50. }
  51. const src_list = props.src.split(",")
  52. src_list.forEach((v) => {
  53. if (props.url) {
  54. Rs.get({
  55. url: props.url + v.split("$")[0],
  56. loading: false,
  57. responseType: "blob"
  58. }).then((res: any) => {
  59. if (res.type === "application/json") {
  60. return
  61. }
  62. const data = new Blob([res])
  63. const url = URL.createObjectURL(data)
  64. srcList.value.push(url)
  65. })
  66. } else {
  67. const url = formatUrl(v)
  68. srcList.value.push(url)
  69. }
  70. })
  71. }
  72. function init() {
  73. load()
  74. }
  75. function onLoad(e: any) {
  76. props.load && props.load(e)
  77. }
  78. function onError(e: any) {
  79. props.error && props.error(e)
  80. }
  81. onMounted(init)
  82. </script>
  83. <template>
  84. <el-image
  85. v-for="(v, i) in srcList"
  86. :key="i"
  87. :fit="fit"
  88. :src="`${v}`"
  89. :initial-index="i"
  90. :style="imgStyle"
  91. :preview-src-list="srcList"
  92. @load="onLoad"
  93. @error="onError"
  94. append-to-body="true">
  95. <template #error>
  96. <div class="image-slot">
  97. <el-icon><picture-filled /></el-icon>
  98. </div>
  99. </template>
  100. </el-image>
  101. </template>
  102. <style lang="scss" scoped>
  103. .el-image {
  104. border-radius: 5px;
  105. background-color: #ebeef5;
  106. box-shadow: 0 0 5px 1px #ccc;
  107. :deep(.el-image__inner) {
  108. transition: all 0.3s;
  109. cursor: pointer;
  110. &:hover {
  111. transform: scale(1.2);
  112. }
  113. }
  114. :deep(.image-slot) {
  115. display: flex;
  116. justify-content: center;
  117. align-items: center;
  118. width: 100%;
  119. height: 100%;
  120. color: #909399;
  121. font-size: 30px;
  122. }
  123. }
  124. </style>