vue.js框架图片上传组件
html:
<div id="app"> <div class="hello"> <div class="upload"> <div class="upload_warp"> <!-- 点击打开文件 --> <div class="upload_warp_left" v-on:click="fileClick"> <img src="upload.png" alt=""> </div> <!-- 点击打开文件 end --> <!-- 将文件拖到此处 --> <div class="upload_warp_right" v-on:drop="drop($event)" v-on:dragenter="dragenter($event)" v-on:dragover="dragover($event)"> 或将文件拖到此处 </div> <!-- 将文件拖到此处 end --> </div> <div class="clear"></div> <!-- 图片 end --> <!-- 这个是标签上的选择文件 --> <input type="file" id="upload_file" multiple style="display: none;" v-on:change="fileChange($event)"> <div class="upload_warp_text"> 选中{{imgList.length}}张文件,共{{bytesToSize(this.size)}} </div> <div class="upload_warp_img" v-show="imgList.length!=0"> <div class="upload_warp_img_div" v-for="(item,index) of imgList"> <div class="upload_warp_img_div_top"> <div class="upload_warp_img_div_text"> {{item.file.name}} </div> <img src="./del.png" class="upload_warp_img_div_del" @click="fileDel(index)"> </div> <img :src="item.file.src"> </div> </div> </div> </div> </div>
css:
.upload { border: 1px solid #ccc; background-color: #fff; width: 650px; box-shadow: 0px 1px 0px #ccc; border-radius: 4px; } .hello{ width: 700px; height: 240px; /*border: 1px solid #999;*/ margin: 20px auto; border-radius: 10px; text-align: center; } .upload_warp{ padding: 20px; } .upload_warp_left{ width: 40%; height: 150px; border: 1px dashed #999; float: left; border-radius: 10px; } .upload_warp_left img{ margin-top: 45px; } .upload_warp_right{ width: 55%; height: 150px; line-height: 150px; border: 1px dashed #999; float: right; border-radius: 10px; color: #999; } .upload_warp_text{ height: 50px; line-height: 50px; border-top: 1px solid #999; margin-top: 20px; } .clear{ clear: both; } .upload_warp_img { border-top: 1px solid #D2D2D2; padding: 14px 0 0 14px; overflow: hidden } .upload_warp_img_div { position: relative; height: 100px; width: 120px; border: 1px solid #ccc; margin: 0px 30px 10px 0px; float: left; line-height: 100px; display: table-cell; text-align: center; background-color: #eee; cursor: pointer; } .upload_warp_img_div img { max-width: 100%; max-height: 100%; vertical-align: middle; } .upload_warp_img_div_top { position: absolute; top: 0; width: 100%; height: 30px; background-color: rgba(0, 0, 0, 0.4); line-height: 30px; text-align: left; color: #fff; font-size: 12px; text-indent: 4px; } .upload_warp_img_div_del { position: absolute; top: 6px; width: 16px; right: 4px; }
js:
new Vue({ el:'#app', data(){ return{ imgList:[], size: 0 } }, methods:{ fileClick(){ document.getElementById('upload_file').click() }, fileChange(el){ if (!el.target.files[0].size) return; this.fileList(el.target.files); el.target.value = '' }, fileList(files){ for(let i = 0; i < files.length; i++){ this.fileAdd(files[i]); } }, // 添加 fileAdd(file){ this.size = this.size + file.size; let reader = new FileReader(); reader.vue = this; reader.readAsDataURL(file); reader.onload = function (){ file.src = this.result; this.vue.imgList.push({ file }); } }, // 删除 fileDel(index){ this.size = this.size - this.imgList[index].file.size; this.imgList.splice(index,1); }, // 容量的多少 bytesToSize(bytes){ if(bytes === 0) return '0 B'; let k = 1000, sizes = ['B','KB','MB','GB','TB','PB','EB','ZB','YB'], i = Math.floor(Math.log(bytes) / Math.log(k)); return (bytes / Math.pow(k,i)).toPrecision(3) + ' ' + sizes[i]; }, dragenter(el){ el.stopPropagation(); el.preventDefault(); }, dragover(el){ el.stopPropagation(); el.preventDefault(); }, drop(el){ el.stopPropagation(); el.preventDefault(); this.fileList(el.dataTransfer.files); } } })