image-viewer.vue 2.2 KB

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