app-upload-image.vue 7.9 KB

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