2/16 Vue 上传图片并预览的实现 ( 一 )
2021-02-19 01:20
标签:解决 机制 opacity 文件大小 drop idt value src nbsp 写在前面 现在还没有上传功能 只差个axios 明天继续写 今天先放个代码 这个东西可以直接复制用 但是上传的文件位置和渲染出来的不一样,估计是底层的东西问题,我没有解决方案 ( for 循环的机制 ) 1 DOCTYPE html>
2 html lang="zh-CN">
3
4 head>
5 meta charset="UTF-8">
6 title>Documenttitle>
7 script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js">script>
8
9 link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
10 head>
11
12 body>
13 div id="app">
14 div class="container">
15
16 div class="title-container">
17 span>上传文件span>
18 div>
19
20 div class="upload-box">
21 div class="drag-box" ref="dragBox" :class="isDrag? ‘draging-drag-box‘:‘‘ ">
22 label>
23 div class="icon-container">
24 i class="fa fa-file" :class="isDrag? ‘draging-fa-file‘: ‘‘">i>
25 div>
26 div class="label-text-container">
27 span :class="isDrag? ‘draging-label-text-container‘:‘‘ ">请将文件拖动至此span>
28 br>
29 span :class="isDrag? ‘draging-label-text-container‘:‘‘ ">或者单击上传span>
30 div>
31 input type="file" accept="image/jepg, image/png" name="pictures"
32 @change="storepreFiles($event.target)" multiple>
33 label>
34 div>
35
36 div class="show-file-box" v-if=" files.length == 0 ? false : true">
37
38 div class="text-container">
39 span>上传列表span>
40 span>{{updateState}} / {{preFilesLength}}span>
41 div>
42
43 div class="pre-upload-bar">
44 div>
45 span>列表加载进度 {{(updateState / preFilesLength).toFixed(1) *100}} %span>
46 div>
47 div class="pre-upload-bar-done"
48 :style="{ width: ( updateState / preFilesLength ) *100 + ‘%‘ }">
49 div>
50 div>
51
52
53 ul class="pre-upload-list">
54 transition-group tag="li" name="list">
55 li class="pre-upload-file" v-for="file in preFiles" :key="file.name">
56 div class="review">
57
58 div class="review-image-container">
59 img class="review-image" :src="file.src">
60 div>
61
62 div class="review-file-name-container">
63 span class="file-name"> {{ file.name }}span>
64 div>
65 div class="progress">
66 div class="progress-done" :style="{ width: file.index + ‘%‘ }">div>
67 div>
68 span class="percent">{{ file.index }}%span>
69 input class="select-box" check type="checkbox" name="select" :value="file.name"
70 :checked="file.isChecked" @change="doSelect(file.name)" ref="select" />
71 div>
72 li>
73 transition-group>
74 ul>
75
76
77 hr color="lightpink" style="margin: 10px 8px;">
78
79 div class="bottom-select">
80 span class="bottom-select-button" @click="seletAll">{{ select }}span>
81 div class="bottom-select-info">
82 div> span>已选span> span class="span-special"
83 :style="{‘color‘: showSize() > 15 ? ‘red‘:‘green‘}">{{showSelect()}} span>
84 span>/{{preFilesLength}}span>
85 div>
86 div> span class="span-special" :style="{‘color‘: showSize() > 15 ? ‘red‘:‘green‘}">{{
87 showSize() }} span> span>/ {{showAllSize()}} mb span>div>
88 div>
89 div>
90
91 div class="bottom-upload">
92 span>上传span>
93 div>
94
95
96 div>
97 div>
98
99 div>
100
101 div>
102 body>
103
104 script>
105 var vm = new Vue({
106 el: ‘#app‘,
107 data() {
108 return {
109 // 预展示的图片对象数组
110 preFiles: [],
111 // preFiles: (function (num) {
112 // var temp = new Array
113 // for (let i = 0; i
114 // temp.push(0)
115 // }
116 // return temp
117 // })(9),
118
119 preFilesLength: 0,
120 // 这个是渲染list的过程 渲染到第几个li
121 updateState: 0,
122
123 // 真正要上传的图片文件
124 files: [],
125
126 // 选择上传的文件
127 select: "全选",
128
129 // 是否进行拖动事件
130 isDrag: false
131 }
132 },
133 updated() {
134 },
135 mounted: function () {
136 var dragBox = this.$refs.dragBox;
137 dragBox.addEventListener(‘dragenter‘, this.onDrag, false);
138 dragBox.addEventListener(‘dragover‘, this.onDrag, false);
139 dragBox.addEventListener(‘dragleave‘, () => { this.isDrag = false; }, false);
140 dragBox.addEventListener(‘drop‘, this.onDrop, false);
141 },
142 watch: {
143 // 通过对 preFiles 监听 实现简单加载文件进度条
144 preFiles: {
145 handler: ‘updateS‘
146 }
147 },
148 methods: {
149 storepreFiles(obj) {
150 // 获取input里面的文件组
151 var fileList = obj.files;
152 // 先判定有没有重复提交的文件 可以加判断条件
153 for (let i = 0; i fileList.length; i++) {
154 for (let j = 0; j this.preFiles.length; j++) {
155 if (this.preFiles[j].name === fileList[i].name) {
156 alert("有文件重复")
157 return
158 }
159 }
160 }
161
162 this.preFilesLength = this.preFilesLength + fileList.length
163
164 // 这样防止变成 两个Filelist 对象 组合
165 for (var i = 0; i fileList.length; i++) {
166 this.files = this.files.concat(fileList[i])
167 }
168 var vue = this
169 //对文件组进行遍历,可以到控制台打印出fileList去看看
170 for (let i = 0; i fileList.length; i++) {
171
172 function uploadFile(file) {
173 return new Promise(function (resolve, reject) {
174 let reader = new FileReader()
175 reader.readAsDataURL(file)
176 reader.onload = function () {
177 resolve(this.result)
178 }
179 })
180 }
181 uploadFile(fileList[i]).then(function (result) {
182 console.group(i)
183 console.log(event)
184 console.log(fileList[i])
185 console.groupEnd()
186 // vue.preFiles.splice(i, 0, { name: fileList[i].name, size: fileList[i].size, index: 0, })
187 vue.preFiles.push({ name: fileList[i].name, size: fileList[i].size, index: 0, src: result, isChecked: true })
188 })
189 }
190 },
191
192 // 渲染列表的参数
193 updateS() {
194 this.updateState = this.updateState + 1
195 },
196
197 findPreFile(name) {
198 let that = this
199 return this.preFiles.find((item, index) => {
200 return item.name === name;
201 })
202
203 },
204
205 // 点击 选择框 和 全选
206 doSelect(name) {
207 this.preFiles.forEach(element => {
208 if (element.name == name) {
209 element.isChecked = !element.isChecked
210 }
211
212 });
213
214 },
215 seletAll() {
216 if (this.$refs.select.find(item => item.checked == false)) {
217 console.log(this.$refs.select)
218 this.preFiles.forEach(element => {
219 element.isChecked = true
220 })
221 }
222
223 },
224
225 // 显示 选中个数 和 显示 选中的文件大小
226 showSelect() {
227 let num = 0
228 this.preFiles.forEach(element => {
229 if (element.isChecked == true) {
230 num++;
231 }
232 });
233 return num
234 },
235
236 showSize() {
237 let size = 0
238 this.preFiles.forEach(element => {
239 if (element.isChecked == true) {
240 size = size + element.size
241 }
242 });
243 return (size / Math.pow(2, 20)).toFixed(2)
244 },
245
246 showAllSize() {
247 let size = 0
248 this.preFiles.forEach(element => {
249
250 size = size + element.size
251 });
252 return (size / Math.pow(2, 20)).toFixed(2)
253
254 },
255
256 // 拖动文件上传
257 onDrag: function (e) {
258 this.isDrag = true;
259 e.stopPropagation();
260 e.preventDefault();
261 // var dragBox = this.$refs.dragBox;
262 // var faFile = this.$refs.faFile;
263 // var textContainer = this.$refs.textContainer;
264
265 // dragBox.onmouseover();
266 // console.log(dragBox)
267
268 },
269
270 onDragLeave(e) {
271
272 },
273
274 onDrop: function (e) {
275 this.isDrag = false;
276 e.stopPropagation();
277 e.preventDefault();
278 var dt = e.dataTransfer;
279 this.storepreFiles(dt);
280 }
281 }
282 });
283
284 script>
285
286 style>
287 span {
288 font-weight: 700;
289 font: bolder;
290 }
291
292 .container {
293 width: 450px;
294 /* background-color: rgb(195, 209, 228); */
295 box-shadow: 2px 2px 2px 2px rgba(68, 68, 68, 0.2);
296 border-radius: 10px;
297 padding: 20px;
298 }
299
300 .upload-box {
301 /* width: 400px; */
302 /* height: 400px; */
303
304 }
305
306 .title-container {
307 margin: 10px 8px 20px 8px;
308 font-size: 20px;
309
310 border-radius: 5px;
311 background: linear-gradient(to right, rgb(112, 158, 242), rgb(255, 255, 255));
312 color: white;
313 }
314
315 .drag-box {
316 padding: 20px;
317 margin: 10px auto;
318 width: 380px;
319 border-radius: 10px;
320 border: 5px dashed rgba(112, 155, 248, 0.7);
321 text-align: center;
322 transition: all linear 0.1s;
323 }
324
325 .label-text-container {
326 margin: 20px 8px;
327 font-size: 20px;
328 }
329
330 .text-container {
331 margin: 20px 8px;
332 font-size: 20px;
333 border-radius: 5px;
334 background: linear-gradient(to right, rgb(112, 158, 242), rgb(255, 255, 255));
335 color: white;
336 }
337
338 .drag-box .label-text-container {
339 color: rgba(190, 190, 190, 0.8);
340 transition: all linear 0.1s;
341 }
342
343 .icon-container {
344 margin: 15px;
345 }
346
347 .fa-file {
348 color: rgba(247, 187, 219, 0.8);
349 font-size: 100px;
350 transition: all linear 0.1s;
351 }
352
353 /* 当进入文件的时候添加css */
354 .drag-box:hover {
355 border: 5px dashed rgba(112, 155, 248, 1);
356 }
357
358 .drag-box:hover .fa-file {
359 color: rgb(245, 124, 188);
360 }
361
362 .drag-box:hover .label-text-container {
363 color: rgb(68, 68, 68);
364 }
365
366
367
368 /* 当拖动文件的时候添加css */
369 .draging-drag-box {
370 border: 5px dashed rgba(112, 155, 248, 1);
371 }
372
373 .draging-fa-file {
374 color: rgb(245, 124, 188);
375 }
376
377 .draging-label-text-container {
378 color: rgb(68, 68, 68);
379 }
380
381 /* 点击上传文件的时候的那个input */
382 label input {
383 display: none;
384 }
385
386
387 .review {
388 border: 1px solid transparent;
389 border-radius: 5px;
390 color: #777;
391 display: flex;
392 font-size: 12px;
393 align-items: center;
394 padding: 10px;
395 margin: 5px 8px;
396 }
397
398 .review:hover {
399 cursor: pointer;
400 /* border: 1px solid #ddd; */
401 box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 0.7);
402 }
403
404 .pre-upload-bar {
405 margin: 10px 10px;
406 height: 20px;
407 }
408
409 .pre-upload-bar span {
410 font-size: 12px;
411 font-weight: 20px;
412 color: #777
413 }
414
415 .pre-upload-bar-done {
416 background: linear-gradient(to left, rgb(112, 158, 242), rgb(119, 140, 255));
417 box-shadow: 0 3px 3px -5px rgb(100, 115, 143), rgb(134, 138, 165);
418 border-radius: 5px;
419 height: 3px;
420 width: 0;
421 transition: width ease 0.2s;
422 }
423
424 .review-file-name-container {
425 width: 100px;
426 }
427
428 .review-image-container {
429 margin: 0 8px 0 0;
430 }
431
432 .review-image {
433 width: 50px;
434 }
435
436 .pre-upload-list {
437 list-style: none;
438 /* 取消缩进 */
439 margin: 0px;
440 padding: 0px
441 }
442
443 .file-name {
444 width: 100%;
445 float: left;
446 overflow: hidden;
447 text-overflow: ellipsis;
448 white-space: normal;
449 }
450
451 .progress {
452 background-color: rgba(100, 100, 100, 0.2);
453 border-radius: 5px;
454 position: relative;
455 margin: 0 10px;
456 height: 10px;
457 width: 150px;
458 }
459
460 .progress-done {
461 background: linear-gradient(to left, rgb(242, 112, 156), rgb(255, 148, 114));
462 box-shadow: 0 3px 3px -5px rgb(242, 112, 156), 0 2px 5px rgb(242, 112, 156);
463 border-radius: 5px;
464 height: 10px;
465 width: 0;
466 transition: width ease 0.1s;
467 }
468
469 .select-box {
470 width: 20px;
471 height: 20px;
472 margin: 0 0 0 36px;
473 }
474
475
476 /* list的transition group */
477 .list-enter,
478 .list-leave-to {
479 opacity: 0;
480 }
481
482 .list-enter-active {
483 animation: moveIn 1s;
484 }
485
486 .list-leave-active {
487 animation: moveOut 1s;
488 /* transition: all 1s linear; */
489 }
490
491 @keyframes moveIn {
492 0% {
493 opacity: 0;
494 transform: translate(30px, 15px);
495 }
496
497 30% {
498 opacity: 0.5;&g
上一篇:web3.js教程
文章标题:2/16 Vue 上传图片并预览的实现 ( 一 )
文章链接:http://soscw.com/index.php/essay/57308.html