easy-upload.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <template>
  2. <view>
  3. <view class="upload">
  4. <block v-for="(upload,index) in uploads" :key="index">
  5. <view class="uplode-file">
  6. <image v-if="types == 'image'" class="uploade-img" :src="upload" :data-src="upload" @tap="previewImage"></image>
  7. <image v-if="types == 'image'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></image>
  8. <video v-if="types == 'video'" class="uploade-img" :src="upload" controls>
  9. <cover-image v-if="types == 'video'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></cover-image>
  10. </video>
  11. </view>
  12. </block>
  13. <view class="uploader-input-box" v-if="uploads.length < uploadCount">
  14. <view class="uploader-input" @tap="chooseUploads"></view>
  15. </view>
  16. </view>
  17. <button type="primary" v-if="types == 'image'" @tap="upload">上传</button>
  18. </view>
  19. </template>
  20. <script>
  21. export default{
  22. props: {
  23. types: {
  24. type: String,
  25. default: 'image'
  26. },
  27. dataList: {
  28. type: Array,
  29. default: function() {
  30. return []
  31. }
  32. },
  33. clearIcon: {
  34. type: String,
  35. default: 'http://img1.imgtn.bdimg.com/it/u=451604666,2295832001&fm=26&gp=0.jpg'
  36. },
  37. uploadUrl: {
  38. type: String,
  39. default: ''
  40. },
  41. deleteUrl: {
  42. type: String,
  43. default: ''
  44. },
  45. uploadCount: {
  46. type: Number,
  47. default: 1
  48. },
  49. //上传图片大小 默认3M
  50. upload_max: {
  51. type: Number,
  52. default: 3
  53. }
  54. },
  55. data(){
  56. return {
  57. //上传的图片地址
  58. uploadImages: [],
  59. //展示的图片地址
  60. uploads: [],
  61. // 超出限制数组
  62. exceeded_list: [],
  63. }
  64. },
  65. watch:{
  66. dataList() {
  67. this.uploads = this.dataList
  68. }
  69. },
  70. methods:{
  71. previewImage (e) {
  72. var current = e.target.dataset.src
  73. uni.previewImage({
  74. current: current,
  75. urls: this.dataList
  76. })
  77. },
  78. chooseUploads(){
  79. switch (this.types){
  80. case 'image':
  81. uni.chooseImage({
  82. count: this.uploadCount - this.uploads.length, //默认9
  83. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  84. sourceType: ['album', 'camera'], //从相册选择
  85. success: (res) => {
  86. for(let i = 0; i< res.tempFiles.length; i++){
  87. if(Math.ceil(res.tempFiles[i].size / 1024) < this.upload_max * 1024){
  88. this.uploads.push(res.tempFiles[i].path)
  89. this.uploadImages.push(res.tempFiles[i].path)
  90. }else {
  91. this.exceeded_list.push(i === 0 ? 1 : i + 1);
  92. uni.showModal({
  93. title: '提示',
  94. content: `第${[...new Set(this.exceeded_list)].join(',')}张图片超出限制${this.upload_max}MB,已过滤`
  95. });
  96. }
  97. }
  98. },
  99. fail: (err) => {
  100. uni.showModal({
  101. content: JSON.stringify(err)
  102. });
  103. }
  104. });
  105. break;
  106. case 'video' :
  107. uni.chooseVideo({
  108. sourceType: ['camera', 'album'],
  109. success: (res) => {
  110. if(Math.ceil(res.size / 1024) < this.upload_max * 1024){
  111. this.uploads.push(res.tempFilePath)
  112. uni.uploadFile({
  113. url: this.uploadUrl, //仅为示例,非真实的接口地址
  114. filePath: res.tempFilePath,
  115. name: 'file',
  116. //请求参数
  117. formData: {
  118. 'user': 'test'
  119. },
  120. success: (uploadFileRes) => {
  121. this.$emit('successVideo',uploadFileRes)
  122. }
  123. });
  124. }else {
  125. uni.showModal({
  126. title: '提示',
  127. content: `第${[...new Set(this.exceeded_list)].join(',')}张视频超出限制${this.upload_max}MB,已过滤`
  128. });
  129. }
  130. },
  131. fail: (err) => {
  132. uni.showModal({
  133. content: JSON.stringify(err)
  134. });
  135. }
  136. });
  137. break;
  138. }
  139. },
  140. delImage(index){
  141. if(this.uploads[index].substring(0,4) !== 'http'){
  142. this.uploads.splice(index,1)
  143. return;
  144. };
  145. if(!this.deleteUrl) {
  146. uni.showModal({
  147. content: '请填写删除接口'
  148. });
  149. return;
  150. };
  151. uni.request({
  152. url: this.deleteUrl,
  153. method: 'DELETE',
  154. data: {
  155. image: this.dataList[index]
  156. },
  157. success: res => {
  158. this.uploads.splice(index,1)
  159. },
  160. });
  161. },
  162. upload(){
  163. debugger
  164. if(!this.uploadUrl) {
  165. uni.showModal({
  166. content: '请填写上传接口'
  167. });
  168. return;
  169. };
  170. for (let i of this.uploadImages) {
  171. uni.uploadFile({
  172. url: this.uploadUrl, //仅为示例,非真实的接口地址
  173. filePath: i,
  174. name: 'file',
  175. //请求参数
  176. formData: {
  177. 'user': 'test'
  178. },
  179. success: (uploadFileRes) => {
  180. this.$emit('successImage',uploadFileRes)
  181. }
  182. });
  183. }
  184. }
  185. }
  186. }
  187. </script>
  188. <style scoped>
  189. .upload {
  190. display: flex;
  191. flex-direction: row;
  192. flex-wrap: wrap;
  193. }
  194. .uplode-file {
  195. margin: 10upx;
  196. width: 210upx;
  197. height: 210upx;
  198. position: relative;
  199. }
  200. .uploade-img {
  201. display: block;
  202. width: 210upx;
  203. height: 210upx;
  204. }
  205. .clear-one{
  206. position: absolute;
  207. top: -10rpx;
  208. right: 0;
  209. }
  210. .clear-one-icon{
  211. position: absolute;
  212. width: 20px;
  213. height: 20px;
  214. top: 0;
  215. right: 0;
  216. z-index: 9;
  217. }
  218. .uploader-input-box {
  219. position: relative;
  220. margin:10upx;
  221. width: 208upx;
  222. height: 208upx;
  223. border: 2upx solid #D9D9D9;
  224. }
  225. .uploader-input-box:before,
  226. .uploader-input-box:after {
  227. content: " ";
  228. position: absolute;
  229. top: 50%;
  230. left: 50%;
  231. -webkit-transform: translate(-50%, -50%);
  232. transform: translate(-50%, -50%);
  233. background-color: #D9D9D9;
  234. }
  235. .uploader-input-box:before {
  236. width: 4upx;
  237. height: 79upx;
  238. }
  239. .uploader-input-box:after {
  240. width: 79upx;
  241. height: 4upx;
  242. }
  243. .uploader-input-box:active {
  244. border-color: #999999;
  245. }
  246. .uploader-input-box:active:before,
  247. .uploader-input-box:active:after {
  248. background-color: #999999;
  249. }
  250. .uploader-input {
  251. position: absolute;
  252. z-index: 1;
  253. top: 0;
  254. left: 0;
  255. width: 100%;
  256. height: 100%;
  257. opacity: 0;
  258. }
  259. </style>