su-image.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <template>
  2. <image
  3. v-if="!state.isError"
  4. class="su-img"
  5. :style="customStyle"
  6. :draggable="false"
  7. :mode="mode"
  8. :src="sheep.$url.cdn(src)"
  9. @tap="onImgPreview"
  10. @load="onImgLoad"
  11. @error="onImgError"
  12. ></image>
  13. </template>
  14. <script setup>
  15. /**
  16. * 图片组件
  17. *
  18. * @property {String} src - 图片地址
  19. * @property {Number} mode - 裁剪方式
  20. * @property {String} isPreview - 是否开启预览
  21. * @property {Number} previewList - 预览列表
  22. * @property {String} current - 预览首张下标
  23. *
  24. * @event {Function} load - 图片加载完毕触发
  25. * @event {Function} error - 图片加载错误触发
  26. *
  27. */
  28. import { reactive, computed } from 'vue';
  29. import sheep from '@/sheep';
  30. // 组件数据
  31. const state = reactive({
  32. isError: false,
  33. imgHeight: 600,
  34. });
  35. // 接收参数
  36. const props = defineProps({
  37. src: {
  38. type: String,
  39. default: '',
  40. },
  41. errorSrc: {
  42. type: String,
  43. default: '/static/img/shop/empty_network.png',
  44. },
  45. mode: {
  46. type: String,
  47. default: 'widthFix',
  48. },
  49. isPreview: {
  50. type: Boolean,
  51. default: false,
  52. },
  53. previewList: {
  54. type: Array,
  55. default() {
  56. return [];
  57. },
  58. },
  59. current: {
  60. type: Number,
  61. default: -1,
  62. },
  63. height: {
  64. type: Number,
  65. default: 0,
  66. },
  67. width: {
  68. type: Number,
  69. default: 0,
  70. },
  71. radius: {
  72. type: Number,
  73. default: 0,
  74. },
  75. });
  76. const emits = defineEmits(['load', 'error']);
  77. const customStyle = computed(() => {
  78. return {
  79. height: (props.height || state.imgHeight) + 'rpx',
  80. width: props.width ? props.width + 'rpx' : '100%',
  81. borderRadius: props.radius ? props.radius + 'rpx' : '',
  82. };
  83. });
  84. // 图片加载完成
  85. function onImgLoad(e) {
  86. if (props.height === 0) {
  87. state.imgHeight = (e.detail.height / e.detail.width) * 750;
  88. }
  89. }
  90. // 图片加载错误
  91. function onImgError(e) {
  92. state.isError = true;
  93. emits('error', e);
  94. }
  95. // 预览图片
  96. function onImgPreview() {
  97. if (!props.isPreview) return;
  98. uni.previewImage({
  99. urls: props.previewList.length < 1 ? [props.src] : props.previewList,
  100. current: props.current,
  101. longPressActions: {
  102. itemList: ['发送给朋友', '保存图片', '收藏'],
  103. success: function (data) {
  104. console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
  105. },
  106. fail: function (err) {
  107. console.log(err.errMsg);
  108. },
  109. },
  110. });
  111. }
  112. </script>
  113. <style lang="scss" scoped>
  114. .su-img {
  115. position: relative;
  116. width: 100%;
  117. height: 100%;
  118. display: block;
  119. }
  120. </style>