pc端vue实现图片上传功能插件简单封装

基于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);}
    }
原文地址:https://www.cnblogs.com/zs521/p/14481624.html