image.uvue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <template>
  2. <view
  3. :class="classList"
  4. v-if="imageData.image != ''"
  5. >
  6. <image
  7. :src="imagePath"
  8. :style="styles"
  9. :alt="imageData.attributes.alt"
  10. class="img"
  11. mode="aspectFill"
  12. @load="imageLoad"
  13. @click="imagePreview"
  14. ></image>
  15. </view>
  16. </template>
  17. <script lang="uts">
  18. import {parseImageUrl} from "@/uni_modules/uni-cms-article/common/parse-image-url.uts";
  19. import type {ParseImageUrlResult} from '@/uni_modules/uni-cms-article/common/parse-image-url.uts';
  20. type ImageAttributes = {
  21. customParams: string | null
  22. width: number | null
  23. height: number | null
  24. alt: string | null
  25. }
  26. type ImageData = {
  27. image: string
  28. attributes: ImageAttributes
  29. }
  30. type ImageCalResult = {
  31. width: number
  32. height: number
  33. }
  34. export default {
  35. name: "render-image",
  36. emits: ['imagePreview'],
  37. props: {
  38. deltaOp: {
  39. type: Object as UTSJSONObject,
  40. default (): UTSJSONObject {
  41. return {}
  42. }
  43. },
  44. reset: {
  45. type: Boolean,
  46. default: false
  47. }
  48. },
  49. data () {
  50. return {
  51. width: 0,
  52. height: 0,
  53. imagePath: ''
  54. }
  55. },
  56. computed: {
  57. imageData (): ImageData {
  58. const insert = this.deltaOp!.getJSON('insert')! as UTSJSONObject
  59. const attributes: UTSJSONObject | null = this.deltaOp!.getJSON('attributes')
  60. console.log(insert, attributes)
  61. return {
  62. image: insert.getString('image')!,
  63. attributes: {
  64. customParams: attributes != null ? attributes.getString('data-custom'): null,
  65. width: attributes != null ? attributes!.getNumber('width'): null,
  66. height: attributes != null ? attributes!.getNumber('height'): null,
  67. alt: attributes != null ? attributes!.getString('alt'): null,
  68. }
  69. } as ImageData
  70. },
  71. classList (): string[] {
  72. return [
  73. 'image',
  74. this.reset ? 'reset': ''
  75. ] as string[]
  76. },
  77. styles (): string {
  78. let style = ""
  79. if (this.width != 0) {
  80. style += `;width:${this.width}px`
  81. }
  82. if (this.height != 0) {
  83. style += `;height:${this.height}px`
  84. }
  85. return style
  86. }
  87. },
  88. mounted () {
  89. this.loadImagePath()
  90. },
  91. methods: {
  92. async loadImagePath (): Promise<void> {
  93. const {image, attributes} = this.imageData
  94. const parseImages = await parseImageUrl({
  95. insert: {image},
  96. attributes: {
  97. 'data-custom': attributes.customParams != null ? attributes.customParams : ""
  98. }
  99. }, "editor")
  100. if (parseImages != null) {
  101. this.imagePath = parseImages[0].src
  102. }
  103. },
  104. imagePreview () {
  105. this.$emit('imagePreview', this.imageData.image)
  106. },
  107. // 图片加载完成
  108. imageLoad(e: ImageLoadEvent) {
  109. const recal = this.wxAutoImageCal(e.detail.width, e.detail.height, 15) // 计算图片宽高
  110. // const image = this.imageData
  111. // ::TODO 关注一下在多端得表现情况
  112. // if (!image.data.attributes.width || Number(image.data.attributes.width) > recal.imageWidth) {
  113. // 如果图片宽度不存在或者图片宽度大于计算出来的宽度,则设置图片宽高
  114. this.width = recal.width
  115. this.height = recal.height
  116. // }
  117. },
  118. // 计算图片宽高
  119. wxAutoImageCal(originalWidth: number, originalHeight: number, imagePadding: number): ImageCalResult {
  120. // 获取系统信息
  121. const systemInfo = uni.getSystemInfoSync()
  122. let windowWidth: number;
  123. // let windowHeight: number;
  124. let autoWidth: number;
  125. let autoHeight: number;
  126. let results: ImageCalResult = {
  127. width: 0,
  128. height: 0
  129. };
  130. // 计算图片宽度
  131. windowWidth = systemInfo.windowWidth - 2 * imagePadding;
  132. // windowHeight = systemInfo.windowHeight;
  133. if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
  134. autoWidth = windowWidth;
  135. autoHeight = (autoWidth * originalHeight) / originalWidth;
  136. results.width = autoWidth;
  137. results.height = autoHeight;
  138. } else {//否则展示原来的数据
  139. results.width = originalWidth;
  140. results.height = originalHeight;
  141. }
  142. return results;
  143. }
  144. }
  145. }
  146. </script>
  147. <style scoped lang="scss">
  148. .image {
  149. margin-bottom: 40rpx;
  150. &.reset {
  151. margin-bottom: 0;
  152. }
  153. .img {
  154. display: flex;
  155. border-radius: 12rpx;
  156. margin: 0 auto;
  157. }
  158. }
  159. </style>