up-load-image.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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','background-color':bgUp}" :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. import uploadFile from '@/core/upload.js';
  22. export default {
  23. name: 'app-upload-image',
  24. props: {
  25. value: {
  26. default: null,
  27. },
  28. defaultImg: {
  29. // 添加图片的默认背景图片
  30. type: String,
  31. default: 'https://shop.9026.com/web/statics/image/mall/static/icon/icon-image.png'
  32. },
  33. maxNum: {
  34. // 可添加最大图片数量
  35. type: [Number, String],
  36. default: 3
  37. },
  38. // 标记
  39. // 当组件用于循环时使用
  40. sign: {
  41. type: String,
  42. default: ''
  43. },
  44. backgroundColor: {
  45. type: String,
  46. default: '#f7f7f7',
  47. },
  48. bgUp: {
  49. type: String,
  50. // default: '#000',
  51. },
  52. margin: {
  53. type: String,
  54. default: '10'
  55. },
  56. diy: {
  57. type: Boolean,
  58. default: false
  59. },
  60. showNumber: {
  61. type: Boolean,
  62. default: true,
  63. },
  64. text: {
  65. type: String,
  66. default: '上传图片',
  67. },
  68. count: {
  69. type: Number,
  70. default: 9
  71. }
  72. },
  73. data() {
  74. return {
  75. imageList: this.value ? this.value : [],
  76. isAddImg: true
  77. }
  78. },
  79. methods: {
  80. // 上传最大图片数量
  81. checkMaxNum() {
  82. let status = this.imageList.length >= this.maxNum ? false : true;
  83. this.isAddImg = status;
  84. },
  85. // 移除图片
  86. remove(index) {
  87. let imageList = this.imageList;
  88. let data = imageList.splice(index, 1);
  89. this.imageList = imageList;
  90. this.checkMaxNum();
  91. // 触发事件 tabEvent
  92. this.$emit('imageEvent', {
  93. imageList: imageList,
  94. sign: this.sign
  95. })
  96. },
  97. // 选择图片
  98. chooseImage() {
  99. let self = this;
  100. let imageList = self.imageList;
  101. // #ifdef MP
  102. uni.chooseImage({
  103. count: self.maxNum,
  104. success: function(e) {
  105. for (let i in e.tempFilePaths) {
  106. if (i >= (self.maxNum - imageList.length)) {
  107. break;
  108. }
  109. let fileName = '';
  110. // #ifdef MP-BAIDU
  111. fileName = e.tempFilePaths[i].substr(e.tempFilePaths[i].lastIndexOf('/') + 1);
  112. // #endif
  113. uni.uploadFile({
  114. url: self.$api.upload.file,
  115. filePath: e.tempFilePaths[i],
  116. name: 'file',
  117. fileType: 'image',
  118. formData: {
  119. file: e.tempFilePaths[i],
  120. file_name: fileName,
  121. },
  122. success(res) {
  123. const data = res.data;
  124. let result = null;
  125. if (typeof data === 'string') {
  126. result = JSON.parse(data);
  127. } else {
  128. result = data;
  129. }
  130. if (result.code == 0) {
  131. imageList.push(result.data.url)
  132. self.imageList = imageList;
  133. self.checkMaxNum();
  134. self.$emit('imageEvent', {
  135. imageList: imageList,
  136. sign: self.sign
  137. });
  138. } else {
  139. uni.showModal({
  140. title: '',
  141. content: result.msg,
  142. showCancel: false,
  143. });
  144. }
  145. },
  146. fail(e) {
  147. if (e && e.errMsg) {
  148. uni.showModal({
  149. title: '错误',
  150. content: e.errMsg,
  151. showCancel: false,
  152. });
  153. }
  154. },
  155. });
  156. }
  157. },
  158. complete: function(e) {
  159. // 触发事件 tabEvent
  160. self.$emit('imageEvent', {
  161. imageList: imageList,
  162. sign: self.sign
  163. })
  164. }
  165. })
  166. // #endif
  167. // #ifdef H5
  168. uni.chooseImage({
  169. count: Number(self.maxNum),
  170. success: function(e) {
  171. for (let i in e.tempFilePaths) {
  172. if (i >= (self.maxNum - imageList.length)) {
  173. break;
  174. }
  175. let image = new Image();
  176. image.src = e.tempFilePaths[i];
  177. image.onload = () => {
  178. let canvas = document.createElement("canvas");
  179. canvas.width = image.width;
  180. canvas.height = image.height;
  181. let ctx = canvas.getContext("2d");
  182. ctx.drawImage(image, 0, 0, image.width, image.height);
  183. let ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase();
  184. let dataURL = canvas.toDataURL("image/" + ext);
  185. uploadFile({
  186. url: self.$api.upload.file,
  187. maxNum: self.maxNum,
  188. success: function({res, header}) {
  189. self.$request({
  190. url: self.$api.upload.file + '&name=base64',
  191. header: header,
  192. method: 'post',
  193. data: {
  194. database: dataURL
  195. }
  196. }).then(res => {
  197. if (res.code === 0) {
  198. self.imageList.push(res.data.url);
  199. self.checkMaxNum();
  200. self.$emit('imageEvent', {
  201. imageList: self.imageList,
  202. sign: self.sign
  203. });
  204. } else {
  205. uni.showModal({
  206. title: '',
  207. content: res.msg,
  208. showCancel: false,
  209. });
  210. }
  211. })
  212. }
  213. });
  214. };
  215. }
  216. },
  217. complete: function(e) {
  218. // 触发事件 tabEvent
  219. self.$emit('imageEvent', {
  220. imageList: imageList,
  221. sign: self.sign
  222. })
  223. }
  224. });
  225. // #endif
  226. },
  227. // 图片预览
  228. previewImage(index) {
  229. let imageList = this.imageList;
  230. uni.previewImage({
  231. current: imageList[index],
  232. urls: imageList
  233. })
  234. },
  235. createObjectURL(blob) {
  236. return (window.URL) ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob);
  237. }
  238. },
  239. created() {
  240. this.checkMaxNum();
  241. }
  242. }
  243. </script>
  244. <style lang="scss" scoped>
  245. .upload-box {
  246. background-color: #fff;
  247. }
  248. .upload-box .title {
  249. padding: 15#{rpx} 0 15#{rpx} 20#{rpx};
  250. }
  251. .upload-box .img {
  252. width: 188#{rpx};
  253. height: 188#{rpx};
  254. margin: 10#{rpx};
  255. display: block;
  256. }
  257. .upload-box .add-img {
  258. width: 188#{rpx};
  259. height: 188#{rpx};
  260. // border: 1#{rpx} dotted $uni-weak-color-one;
  261. background-color: #ECECEC;
  262. }
  263. .upload-box .add-img .text {
  264. color: $uni-general-color-two;
  265. font-size: $uni-font-size-weak-two;
  266. }
  267. .upload-box .add-img-icon {
  268. width: 56#{rpx};
  269. height: 56#{rpx};
  270. margin-bottom: 10#{rpx};
  271. }
  272. .upload-box .img-box {
  273. position: relative;
  274. }
  275. .upload-box .remove {
  276. width: 40#{rpx};
  277. height: 40#{rpx};
  278. position: absolute;
  279. right: 0;
  280. top: 0;
  281. background: rgba($color: #000000, $alpha: 0.5);
  282. color: #fff;
  283. border-radius: 0 10rpx 0 10rpx;
  284. // border-radius: 50%;
  285. padding-bottom: 8#{rpx};
  286. font-size: 24#{rpx};
  287. z-index: 968;
  288. }
  289. .upload-box .add-img.other-border {
  290. border: 1#{rpx} solid $uni-weak-color-one
  291. }
  292. </style>