image-viewer.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <view class="image-viewer" :style="containerStyle">
  3. <image
  4. :src="src"
  5. :mode="mode"
  6. :style="imageStyle"
  7. :lazy-load="lazyLoad"
  8. @load="onImageLoad"
  9. @error="onImageError"
  10. @tap="onImageTap"
  11. ></image>
  12. </view>
  13. </template>
  14. <script>
  15. export default {
  16. name: 'ImageViewer',
  17. props: {
  18. // 图片地址
  19. src: {
  20. type: String,
  21. required: true
  22. },
  23. // 容器宽度
  24. width: {
  25. type: [String, Number],
  26. default: '100%'
  27. },
  28. // 容器高度
  29. height: {
  30. type: [String, Number],
  31. default: 'auto'
  32. },
  33. // 图片展示模式
  34. mode: {
  35. type: String,
  36. default: 'aspectFit',
  37. validator: (value) => {
  38. return ['aspectFit', 'aspectFill', 'widthFix', 'heightFix'].includes(value)
  39. }
  40. },
  41. // 是否懒加载
  42. lazyLoad: {
  43. type: Boolean,
  44. default: true
  45. },
  46. // 图片圆角
  47. radius: {
  48. type: [String, Number],
  49. default: 0
  50. },
  51. // 是否可点击放大
  52. preview: {
  53. type: Boolean,
  54. default: false
  55. }
  56. },
  57. data() {
  58. return {
  59. imageWidth: 0,
  60. imageHeight: 0,
  61. loaded: false
  62. }
  63. },
  64. computed: {
  65. containerStyle() {
  66. const style = {
  67. width: typeof this.width === 'number' ? `${this.width}rpx` : this.width,
  68. height: typeof this.height === 'number' ? `${this.height}rpx` : this.height,
  69. borderRadius: typeof this.radius === 'number' ? `${this.radius}rpx` : this.radius
  70. }
  71. return style
  72. },
  73. imageStyle() {
  74. const style = {
  75. width: '100%',
  76. height: '100%'
  77. }
  78. return style
  79. }
  80. },
  81. methods: {
  82. onImageLoad(e) {
  83. this.loaded = true
  84. this.imageWidth = e.detail.width
  85. this.imageHeight = e.detail.height
  86. this.$emit('load', e)
  87. },
  88. onImageError(e) {
  89. this.$emit('error', e)
  90. },
  91. onImageTap() {
  92. if (this.preview) {
  93. uni.previewImage({
  94. urls: [this.src],
  95. current: this.src
  96. })
  97. }
  98. this.$emit('tap')
  99. }
  100. }
  101. }
  102. </script>
  103. <style lang="scss">
  104. .image-viewer {
  105. position: relative;
  106. overflow: hidden;
  107. width: 100%;
  108. image {
  109. display: block;
  110. transition: opacity 0.3s;
  111. }
  112. }
  113. </style>