app-upload-image.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <view class="app-upload-image">
  3. <view class='upload-box' :style="{'background':backgroundColor}">
  4. <view class='flex-wrap'>
  5. <view v-for='(item, index) in imageList' :key='item.id' class='img-box'>
  6. <view mode="aspectFill" @click='remove(index)' class='remove cross-center main-center'>x</view>
  7. <image @click='previewImage(index)' :src='item' mode="aspectFill" class='img'></image>
  8. </view>
  9. <view @click='chooseImage'>
  10. <view v-if='isAddImg' :style="{'margin':margin + 'rpx'}" :class="{'other-border': diy ? true : false}" class="add-img dir-top-nowrap cross-center main-center">
  11. <image mode="aspectFill" class='add-img-icon' :src='defaultImg'></image>
  12. <text class='text'>{{text}}</text>
  13. <text class='text' v-if="showNumber">(最多{{maxNum}}张)</text>
  14. </view>
  15. </view>
  16. </view>
  17. </view>
  18. </view>
  19. </template>
  20. <script>
  21. export default {
  22. name: 'app-upload-image',
  23. props: {
  24. value: {
  25. default: null,
  26. },
  27. defaultImg: {
  28. // 添加图片的默认背景图片
  29. type: String,
  30. default: '/static/image/icon/icon-image.png'
  31. },
  32. maxNum: {
  33. // 可添加最大图片数量
  34. type: Number,
  35. default: 3
  36. },
  37. // 标记
  38. // 当组件用于循环时使用
  39. sign: {
  40. type: String,
  41. default: ''
  42. },
  43. backgroundColor: {
  44. type: String,
  45. default: '#f7f7f7',
  46. },
  47. margin: {
  48. type: String,
  49. default: '10'
  50. },
  51. diy: {
  52. type: Boolean,
  53. default: false
  54. },
  55. showNumber: {
  56. type: Boolean,
  57. default: true,
  58. },
  59. text: {
  60. type: String,
  61. default: '上传图片',
  62. },
  63. count: {
  64. type: Number,
  65. default: 9
  66. }
  67. },
  68. data() {
  69. return {
  70. imageList: this.value ? this.value : [],
  71. isAddImg: true
  72. }
  73. },
  74. methods: {
  75. // 上传最大图片数量
  76. checkMaxNum() {
  77. let status = this.imageList.length >= this.maxNum ? false : true;
  78. this.isAddImg = status;
  79. },
  80. // 移除图片
  81. remove(index) {
  82. let imageList = this.imageList;
  83. let data = imageList.splice(index, 1);
  84. this.imageList = imageList;
  85. this.checkMaxNum();
  86. // 触发事件 tabEvent
  87. this.$emit('imageEvent', {
  88. imageList: imageList,
  89. sign: this.sign
  90. })
  91. },
  92. // 选择图片
  93. chooseImage() {
  94. let self = this;
  95. let imageList = self.imageList;
  96. uni.chooseImage({
  97. count: self.maxNum,
  98. success: function(e) {
  99. for (let i in e.tempFilePaths) {
  100. if (i >= (self.maxNum - imageList.length)) {
  101. break;
  102. }
  103. let fileName = '';
  104. // #ifdef MP-BAIDU
  105. fileName = e.tempFilePaths[i].substr(e.tempFilePaths[i].lastIndexOf('/') + 1);
  106. // #endif
  107. uni.uploadFile({
  108. url: self.$api.upload.file,
  109. filePath: e.tempFilePaths[i],
  110. name: 'file',
  111. fileType: 'image',
  112. formData: {
  113. file: e.tempFilePaths[i],
  114. file_name: fileName,
  115. },
  116. success(res) {
  117. const data = res.data;
  118. let result = null;
  119. if (typeof data === 'string') {
  120. result = JSON.parse(data);
  121. } else {
  122. result = data;
  123. }
  124. if (result.code == 0) {
  125. imageList.push(result.data.url)
  126. self.imageList = imageList;
  127. self.checkMaxNum();
  128. self.$emit('imageEvent', {
  129. imageList: imageList,
  130. sign: self.sign
  131. })
  132. } else {
  133. uni.showModal({
  134. title: '',
  135. content: result.msg,
  136. showCancel: false,
  137. })
  138. }
  139. },
  140. fail(e) {
  141. if (e && e.errMsg) {
  142. uni.showModal({
  143. title: '错误',
  144. content: e.errMsg,
  145. showCancel: false,
  146. });
  147. }
  148. },
  149. });
  150. }
  151. },
  152. complete: function(e) {
  153. // 触发事件 tabEvent
  154. self.$emit('imageEvent', {
  155. imageList: imageList,
  156. sign: self.sign
  157. })
  158. }
  159. })
  160. },
  161. // 图片预览
  162. previewImage(index) {
  163. let imageList = this.imageList;
  164. uni.previewImage({
  165. current: imageList[index],
  166. urls: imageList
  167. })
  168. },
  169. },
  170. created() {
  171. this.checkMaxNum();
  172. }
  173. }
  174. </script>
  175. <style lang="scss" scoped>
  176. .upload-box {
  177. background-color: #fff;
  178. }
  179. .upload-box .title {
  180. padding: 15#{rpx} 0 15#{rpx} 20#{rpx};
  181. }
  182. .upload-box .img {
  183. width: 188#{rpx};
  184. height: 188#{rpx};
  185. margin: 10#{rpx};
  186. display: block;
  187. }
  188. .upload-box .add-img {
  189. width: 188#{rpx};
  190. height: 188#{rpx};
  191. border: 1#{rpx} dotted $uni-weak-color-one;
  192. background-color: #fff;
  193. }
  194. .upload-box .add-img .text {
  195. color: $uni-general-color-two;
  196. font-size: $uni-font-size-weak-two;
  197. }
  198. .upload-box .add-img-icon {
  199. width: 56#{rpx};
  200. height: 56#{rpx};
  201. margin-bottom: 10#{rpx};
  202. }
  203. .upload-box .img-box {
  204. position: relative;
  205. }
  206. .upload-box .remove {
  207. width: 40#{rpx};
  208. height: 40#{rpx};
  209. position: absolute;
  210. right: -5rpx;
  211. top: -10rpx;
  212. background: $uni-important-color-red;
  213. color: #fff;
  214. border-radius: 50%;
  215. padding-bottom: 8#{rpx};
  216. font-size: 24#{rpx};
  217. }
  218. .upload-box .add-img.other-border {
  219. border: 1#{rpx} solid $uni-weak-color-one
  220. }
  221. </style>