easy-upload.vue 6.7 KB

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