tm-images.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <template>
  2. <view @click="click" class="tm-images overflow fulled " :class="[round=='rounded'?'rounded':`round-${round}`]">
  3. <view class="fulled fulled-height tm-images-load flex-center">
  4. <view class="d-inline-block load">
  5. <text v-if="isLoad" class="iconfont icon-loading text-size-n text-grey"></text>
  6. </view>
  7. <view class="d-inline-block" v-if="isError">
  8. <slot name="error">
  9. <text class="iconfont icon-exclamationcircle-f text-size-xl text-grey-lighten-2"></text>
  10. </slot>
  11. </view>
  12. <image v-show="!isLoad" @error="error"
  13. :class="[round=='rounded'?'rounded':`round-${round}`]"
  14. :style="{
  15. width:w+'px',
  16. height:h+'px'
  17. }"
  18. @load="loadPic" :src="src_path" :mode="model"></image>
  19. </view>
  20. </view>
  21. </template>
  22. <script>
  23. /**
  24. * 图片
  25. * @property {Function} load 加载成功时触发返回图片宽高。
  26. * @property {Function} click 点击图片事件,返回图片地址参数。
  27. * @property {Function} error 图片加载出错时触发。
  28. * @property {String} src = [] 默认:"",必填。图片地址。测试图片:https://picsum.photos/300
  29. * @property {Number} width = [] 默认:0,宽度,非必填,单位rpx
  30. * @property {Number} height = [] 默认:0,高度,非必填,单位rpx
  31. * @property {Number} round = [] 默认:0,圆角,非必填
  32. * @property {Boolean|String} previmage = [true|false] 默认:true,点击图片是否预览。
  33. * @property {String} model = [scaleToFill|aspectFit|aspectFill|widthFix|heightFix|top|bottom|center|left|right|top left|top right|bottom left|bottom right] 默认:scaleToFill,图片展现模式,同官方。
  34. * @example <tm-images src="https://picsum.photos/300"></tm-images>
  35. */
  36. export default {
  37. name: "tm-images",
  38. props: {
  39. src: {
  40. type: String,
  41. default: ""
  42. },
  43. //自动,宽度撑满容器宽度,高度自动。
  44. // 自定宽度,
  45. width: {
  46. type: Number,
  47. default: 0
  48. },
  49. // 自定高度。
  50. height: {
  51. type: Number,
  52. default: 0
  53. },
  54. // 是否开启预览模式,即点击图片可以预览。
  55. previmage: {
  56. type: Boolean | String,
  57. default: true
  58. },
  59. model: {
  60. type: String,
  61. default: 'scaleToFill'
  62. },
  63. round: {
  64. type: Number|String,
  65. default: 0
  66. }
  67. },
  68. data() {
  69. return {
  70. w: 0,
  71. h: 0,
  72. isLoad:false,
  73. isError:false
  74. };
  75. },
  76. computed:{
  77. w_px:function(){
  78. return uni.upx2px(this.width);
  79. },
  80. h_px:function(){
  81. return uni.upx2px(this.height);
  82. },
  83. src_path:function(){
  84. if(
  85. this.src.substring(0,4)=='http'||
  86. this.src.substring(0,4)=='blob'||
  87. this.src.substring(0,5)=='https'||
  88. this.src.substring(0,3)=='ftp'||
  89. this.src.indexOf('data:image')>-1
  90. ){
  91. return this.src;
  92. }
  93. return '/'+this.src;
  94. }
  95. },
  96. mounted() {
  97. this.isLoad = true;
  98. },
  99. methods: {
  100. error(e) {
  101. this.isLoad = false;
  102. this.isError = true;
  103. this.$emit('error', e);
  104. },
  105. async loadPic(e) {
  106. let wh = e.detail;
  107. this.isLoad = false;
  108. this.isError = false;
  109. this.$nextTick(async function(){
  110. this.$Querey(".tm-images",this,30).then(tb=>{
  111. let sw = tb[0].width||wh.width;
  112. let sh = tb[0].height||wh.height;
  113. let bl = wh.width / wh.height;
  114. if (this.w_px == 0 && this.h_px == 0) {
  115. this.w = sw;
  116. this.h = sw / bl;
  117. this.$emit('load', {
  118. width: this.w,
  119. height: this.h
  120. })
  121. return;
  122. }
  123. if (this.w_px == 0 && this.h_px > 0) {
  124. this.w = this.h_px * bl;
  125. this.h = this.h_px
  126. this.$emit('load', {
  127. width: this.w,
  128. height: this.h
  129. })
  130. return;
  131. }
  132. if (this.w_px > 0 && this.h_px == 0) {
  133. this.w = this.w_px;
  134. this.h = this.w_px / bl
  135. this.$emit('load', {
  136. width: this.w,
  137. height: this.h
  138. })
  139. return;
  140. }
  141. if (this.w_px > 0 && this.h_px > 0) {
  142. this.w = this.w_px;
  143. this.h = this.h_px;
  144. this.$emit('load', {
  145. width: this.w,
  146. height: this.h
  147. })
  148. return;
  149. }
  150. })
  151. })
  152. },
  153. click(e) {
  154. this.$emit("click", this.src_path);
  155. if (this.previmage&&!this.isError) {
  156. uni.previewImage({
  157. current: this.src_path,
  158. urls: [this.src_path],
  159. fail:(res)=>{
  160. }
  161. })
  162. }
  163. }
  164. },
  165. }
  166. </script>
  167. <style lang="scss" scoped>
  168. .tm-images{
  169. line-height: 0;
  170. .tm-images-load{
  171. min-width: 60rpx;
  172. min-height: 60rpx;
  173. .load{
  174. animation: xhRote 0.8s infinite linear;
  175. }
  176. }
  177. }
  178. @keyframes xhRote{
  179. 0%{
  180. transform: rotate(0deg);
  181. }
  182. 100%{
  183. transform: rotate(360deg);
  184. }
  185. }
  186. </style>