Vue上传图片功能实现

适用UI库

一、Vant中的Uploader组件

二、cube-ui中的Upload 组件

没有使用UI库

  1 <!DOCTYPE html>
  2 <html >
  3 <head>
  4   <meta charset="UTF-8">
  5   <title>Title</title>
  6   <script src="http://www.jq22.com/jquery/vue.min.js"></script>
  7   <style>
  8     .upload_warp_img_div_del {
  9       position: absolute;
 10       top: 6px;
 11       width: 16px;
 12       right: 4px;
 13     }
 14 
 15     .upload_warp_img_div_top {
 16       position: absolute;
 17       top: 0;
 18       width: 100%;
 19       height: 30px;
 20       background-color: rgba(0, 0, 0, 0.4);
 21       line-height: 30px;
 22       text-align: left;
 23       color: #fff;
 24       font-size: 12px;
 25       text-indent: 4px;
 26     }
 27 
 28     .upload_warp_img_div_text {
 29       white-space: nowrap;
 30       width: 80%;
 31       overflow: hidden;
 32       text-overflow: ellipsis;
 33     }
 34 
 35     .upload_warp_img_div img {
 36       max-width: 100%;
 37       max-height: 100%;
 38       vertical-align: middle;
 39     }
 40 
 41     .upload_warp_img_div {
 42       position: relative;
 43       height: 100px;
 44       width: 120px;
 45       border: 1px solid #ccc;
 46       margin: 0px 30px 10px 0px;
 47       float: left;
 48       line-height: 100px;
 49       display: table-cell;
 50       text-align: center;
 51       background-color: #eee;
 52       cursor: pointer;
 53     }
 54 
 55     .upload_warp_img {
 56       border-top: 1px solid #D2D2D2;
 57       padding: 14px 0 0 14px;
 58       overflow: hidden
 59     }
 60 
 61     .upload_warp_text {
 62       text-align: left;
 63       margin-bottom: 10px;
 64       padding-top: 10px;
 65       text-indent: 14px;
 66       border-top: 1px solid #ccc;
 67       font-size: 14px;
 68     }
 69 
 70     .upload_warp_right {
 71       float: left;
 72       width: 57%;
 73       margin-left: 2%;
 74       height: 100%;
 75       border: 1px dashed #999;
 76       border-radius: 4px;
 77       line-height: 130px;
 78       color: #999;
 79     }
 80 
 81     .upload_warp_left img {
 82       margin-top: 32px;
 83     }
 84 
 85     .upload_warp_left {
 86       float: left;
 87       width: 40%;
 88       height: 100%;
 89       border: 1px dashed #999;
 90       border-radius: 4px;
 91       cursor: pointer;
 92     }
 93 
 94     .upload_warp {
 95       margin: 14px;
 96       height: 130px;
 97     }
 98 
 99     .upload {
100       border: 1px solid #ccc;
101       background-color: #fff;
102       width: 650px;
103       box-shadow: 0px 1px 0px #ccc;
104       border-radius: 4px;
105     }
106 
107     .hello {
108       width: 650px;
109       margin-left: 34%;
110       text-align: center;
111     }
112   </style>
113 </head>
114 <body>
115 <div >
116   <div class="hello">
117     <div class="upload">
118       <div class="upload_warp">
119         <div class="upload_warp_left" @click="fileClick">
120           <img src="./upload.png">
121         </div>
122         <div class="upload_warp_right" @drop="drop($event)" @dragenter="dragenter($event)" @dragover="dragover($event)">
123           或者将文件拖到此处
124         </div>
125       </div>
126       <div class="upload_warp_text">
127         选中{{imgList.length}}张文件,共{{bytesToSize(this.size)}}
128       </div>
129       <input @change="fileChange($event)" type="file" />
130       <div class="upload_warp_img" v-show="imgList.length!=0">
131         <div class="upload_warp_img_div" v-for="(item,index) of imgList">
132           <div class="upload_warp_img_div_top">
133             <div class="upload_warp_img_div_text">
134               {{item.file.name}}
135             </div>
136             <img src="./del.png" class="upload_warp_img_div_del" @click="fileDel(index)">
137           </div>
138           <img :src="item.file.src">
139         </div>
140       </div>
141     </div>
142   </div>
143 </div>
144 <script>
145   //  import up from  './src/components/Hello'
146   var app = new Vue({
147     el: '#app',
148     data () {
149       return {
150         imgList: [],
151         size: 0
152       }
153     },
154       methods: {
155           fileClick() {
156               document.getElementById('upload_file').click()
157           },
158           fileChange(el) {
159               if (!el.target.files[0].size) return;
160               this.fileList(el.target);
161               el.target.value = ''
162           },
163           fileList(fileList) {
164               let files = fileList.files;
165               for (let i = 0; i < files.length; i++) {
166                   //判断是否为文件夹
167                   if (files[i].type != '') {
168                       this.fileAdd(files[i]);
169                   } else {
170                       //文件夹处理
171                       this.folders(fileList.items[i]);
172                   }
173               }
174           },
175           //文件夹处理
176           folders(files) {
177               let _this = this;
178               //判断是否为原生file
179               if (files.kind) {
180                   files = files.webkitGetAsEntry();
181               }
182               files.createReader().readEntries(function (file) {
183                   for (let i = 0; i < file.length; i++) {
184                       if (file[i].isFile) {
185                           _this.foldersAdd(file[i]);
186                       } else {
187                           _this.folders(file[i]);
188                       }
189                   }
190               })
191           },
192           foldersAdd(entry) {
193               let _this = this;
194               entry.file(function (file) {
195                   _this.fileAdd(file)
196               })
197           },
198           fileAdd(file) {
199               //总大小
200               this.size = this.size + file.size;
201               //判断是否为图片文件
202               if (file.type.indexOf('image') == -1) {
203                   file.src = 'wenjian.png';
204                   this.imgList.push({
205                       file
206                   });
207               } else {
208                   let reader = new FileReader();
209                   reader.vue = this;
210                   reader.readAsDataURL(file);
211                   reader.onload = function () {
212                       file.src = this.result;
213                       this.vue.imgList.push({
214                           file
215                       });
216                   }
217               }
218           },
219           fileDel(index) {
220               this.size = this.size - this.imgList[index].file.size;//总大小
221               this.imgList.splice(index, 1);
222           },
223           bytesToSize(bytes) {
224               if (bytes === 0) return '0 B';
225               let k = 1000, // or 1024
226                   sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
227                   i = Math.floor(Math.log(bytes) / Math.log(k));
228               return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
229           },
230           dragenter(el) {
231               el.stopPropagation();
232               el.preventDefault();
233           },
234           dragover(el) {
235               el.stopPropagation();
236               el.preventDefault();
237           },
238           drop(el) {
239               el.stopPropagation();
240               el.preventDefault();
241               this.fileList(el.dataTransfer);
242           }
243       }
244   })
245 </script>
246 </body>
247 </html>