easy-upload.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. if(!this.uploadUrl) {
  164. uni.showModal({
  165. content: '请填写上传接口'
  166. });
  167. return;
  168. };
  169. for (let i of this.uploadImages) {
  170. uni.uploadFile({
  171. url: this.uploadUrl, //仅为示例,非真实的接口地址
  172. filePath: i,
  173. name: 'file',
  174. //请求参数
  175. formData: {
  176. 'user': 'test'
  177. },
  178. success: (uploadFileRes) => {
  179. this.$emit('successImage',uploadFileRes)
  180. }
  181. });
  182. }
  183. }
  184. }
  185. }
  186. </script>
  187. <style scoped>
  188. .upload {
  189. display: flex;
  190. flex-direction: row;
  191. flex-wrap: wrap;
  192. }
  193. .uplode-file {
  194. margin: 10upx;
  195. width: 210upx;
  196. height: 210upx;
  197. position: relative;
  198. }
  199. .uploade-img {
  200. display: block;
  201. width: 210upx;
  202. height: 210upx;
  203. }
  204. .clear-one{
  205. position: absolute;
  206. top: -10rpx;
  207. right: 0;
  208. }
  209. .clear-one-icon{
  210. position: absolute;
  211. width: 20px;
  212. height: 20px;
  213. top: 0;
  214. right: 0;
  215. z-index: 9;
  216. }
  217. .uploader-input-box {
  218. position: relative;
  219. margin:10upx;
  220. width: 208upx;
  221. height: 208upx;
  222. border: 2upx solid #D9D9D9;
  223. }
  224. .uploader-input-box:before,
  225. .uploader-input-box:after {
  226. content: " ";
  227. position: absolute;
  228. top: 50%;
  229. left: 50%;
  230. -webkit-transform: translate(-50%, -50%);
  231. transform: translate(-50%, -50%);
  232. background-color: #D9D9D9;
  233. }
  234. .uploader-input-box:before {
  235. width: 4upx;
  236. height: 79upx;
  237. }
  238. .uploader-input-box:after {
  239. width: 79upx;
  240. height: 4upx;
  241. }
  242. .uploader-input-box:active {
  243. border-color: #999999;
  244. }
  245. .uploader-input-box:active:before,
  246. .uploader-input-box:active:after {
  247. background-color: #999999;
  248. }
  249. .uploader-input {
  250. position: absolute;
  251. z-index: 1;
  252. top: 0;
  253. left: 0;
  254. width: 100%;
  255. height: 100%;
  256. opacity: 0;
  257. }
  258. </style>