基於vue實現的圖片上傳功能,簡單的封裝,可以直接根據自己的需求修改
效果圖
案例中的小圖標引用了阿里雲矢量圖標庫,建議換成自己的
<link rel="stylesheet" href="//at.alicdn.com/t/font_2400323_baxifjc4jkt.css">
html部分
<template> <div class="upload-img"> <ul class="upload-list"> <li v-for="(item,index) in picList" :key="index"> <img :src="item" alt=""> <div class="caozuo"> <i @click="previewImg(item,index)" class="iconfont icon-fangda"></i> <i @click="deleteImg(item,index)" class="iconfont icon-delete"></i> </div> </li> <li class="add-img"> <input @change="fileChange" type="file" > <i v-if="!loading" class="iconfont icon-tianjia"></i> <i v-else class="iconfont loading icon-jiazai"></i> </li> </ul> <div class="preview-box" v-if="ispreview" @click.self="ispreview=false"> <img :src="previewItem" alt=""> </div> </div> </template>
js部分
<script> export default{ data(){ return { picList:['https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3269311786,2664508790&fm=26&gp=0.jpg', 'https://t7.baidu.com/it/u=3358371731,3444613872&fm=193&f=GIF', 'https://t7.baidu.com/it/u=2658433172,2362704784&fm=193&f=GIF'], loading:false, //加載效果 previewItem:'', //用於預覽 ispreview:false, //是否打開預覽 } }, props:{ num:{ type:Number, default:3 //限制圖片的張數 } }, mounted(){ }, methods:{ fileChange(e){ var arr=e.target.files; var picList=this.localPreview(arr) if(this.picList.length==this.num){ alert('最多只能上傳'+this.num+'張') return } this.loading=true setTimeout(()=>{ this.picList.push(...picList) this.loading=false },3000) this.$emit('changepic',this.picList) //下面是調用接口時候用的 // var formData = new FormData() // arr.forEach(item=>{ // formData.append('file',item) // }) /**發起請求自己根據自己的需求寫**/ // }, //刪除圖片 deleteImg(item,index){ this.picList.splice(index,1) this.$emit('changepic',this.picList) }, //預覽圖片 previewImg(item,index){ this.ispreview=true this.previewItem=item this.$emit('preview',item) }, /***獲取圖片上傳的本地路徑****/ localPreview(list){ //這里是利用文件讀取對象讀取圖片 // var reader = new FileReader(); // reader.readAsDataURL(file); // var url=null; // reader.onload=function(){ // url=reader.result; // } var url=null; var arr=[] list.forEach(item=>{ arr.push(window.URL.createObjectURL(item)) //利用window.URL.createObjectURL轉換 }) return arr } }, } </script>
css部分
ul,li{ padding:0px; margin:0px; list-style: none; } p{ padding:0px; margin:0px; } .upload-list{ width:100%; display:flex; flex-wrap: wrap; } .upload-list li{ width:100px; position:relative; margin:5px; height:100px; border:1px solid black; overflow:hidden; box-sizing: border-box; } .upload-list li:hover .caozuo{ display:flex; } .caozuo{ display:none; background:rgba(0,0,0,0.5); position:absolute; left:0px; top:0px; width:100%; height:100%; justify-content: center; align-items: center; color:white; letter-spacing: 5px; } .caozuo .iconfont{ font-size:25px; } .upload-list li img{ width:100%; position:absolute; left:0px; top:50%; transform: translateY(-50%); } .upload-img{ width:100%; } .add-img{ width:32%; display:flex; justify-content: center; align-items: center; } .add-img .iconfont{ font-size:40px; } .add-img input{ position:absolute; left:0px; bottom:0px; width:100%; height:100%; opacity: 0; z-index:1; } .loading{ animation:carton 5s infinite; } .preview-box{ display:flex; justify-content: center; align-items: center; position:fixed; top:0px; left:0px; right:0px; bottom:0px; background:rgba(0,0,0,0.5) } .preview-box img{ max-width:100%; max-height:100%; } @keyframes carton { from {transform:rotate(0deg);} to {transform:rotate(360deg);} }