封装 el-upload,实现可上传图片、预览图片、编辑图片、删除图片功能

本文介绍了一个基于Vue的图片上传组件的实现细节,该组件支持多种图片格式,具备预览、编辑及删除等功能,并能将图片数据传递给父组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图

在这里插入图片描述

父组件
template
<el-card>
            <div>上传图片子组件</div>
            <el-form label-width="100px">
                <el-form-item label="图片:">
                    <uploadImg :limit="5" :fileList="fileList" @submitImg="getImgList"></uploadImg>
                </el-form-item>
            </el-form>
        </el-card>
script
//数据
data(){
	return:{
		fileList:[
                {name:'大宝贝',url:'https://i.ebayimg.com/00/s/ODAwWDgwMA==/z/MO4AAOSwjYFezOIR/$_12.JPG?set_id=880000500F'},
                {name:'滴滴滴',url:'https://i.ebayimg.com/00/s/OTAwWDkwMA==/z/a60AAOSwaYdfG7vI/$_12.JPG?set_id=880000500F'},  
            ],
	}
}
// 获取图片
 getImgList(list){
     this.fileList = list
 }
子组件 uploadImg (完整代码)
<template>
    <div>
        <el-upload
            :action="action"
            list-type="picture-card"
            accept=".jpg,.jpeg,.png"
            :on-success="handleSuccess"
            :file-list="fileLists"
            :headers="{username:username}"
            :disabled="fileLists.length >= limit">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
                <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
                <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                        <i class="el-icon-zoom-in"></i>
                    </span>
                    <span class="el-upload-list__item-edit" @click="handlePictureCardEdit(file)">
                        <i class="el-icon-edit"></i>
                    </span>
                    <span class="el-upload-list__item-delete" @click="handleRemove(file)">
                        <i class="el-icon-delete"></i>
                    </span>
                </span>
            </div>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible" append-to-body>
            <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
        <el-dialog :visible.sync="editView" width="40%" append-to-body>
            <el-input type="textarea" :rows="4" v-model="editForm.url" @input="editPic"></el-input>
        </el-dialog>
    </div>
</template>

<script>
export default {
    props:{
        limit:{
            type:Number,
            default:12,
        },
        action:{
            type:String,
            default:'#'
        },
        fileList:{
            type:Array,
            default: ()=>{
                return []
            }
        }
    },
    data(){
        return{
            dialogImageUrl: '',
            dialogVisible: false,
            fileLists:this.fileList,
            editForm:{
                url:'',
                uid:null
            },
            editView:false,
            username:''
        }
    },
    mounted(){
        this.username = Cookies.get('username')
    },
    methods:{
        // 移除图片
        handleRemove(file) {
            for(let i in this.fileLists){
                if(this.fileLists[i].uid == file.uid){
                    this.fileLists.splice(i,1)
                }
            }
            this.submitFile()
        },
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
        handleSuccess(response,file,fileList){
            let obj = {
                name: file.name,
                status: "success",
                uid: file.uid,
                url: file.url,
            }
            this.fileLists.push(obj)
            this.submitFile()
        },
        // 编辑图片弹窗
        handlePictureCardEdit(file){
            this.editForm.url = file.url
            this.editForm.uid = file.uid
            this.editView = true
        },
        // 编辑图片
        editPic(){
            for(let i in this.fileLists){
                if(this.fileLists[i].uid == this.editForm.uid){
                    this.fileLists[i].url = this.editForm.url
                }
            }
            this.submitFile()
        },
        // 将图片文件传回给父组件
        submitFile(){
            this.$emit('submitImg',this.fileLists)
        },
    }
}
</script>

<style scoped>
    .el-icon-plus{
        font-size: 30px!important;
    }
    .el-icon-edit{
        font-size: 18px !important;
    }
    .el-icon-zoom-in{
        font-size: 18px !important;
    }
    .el-icon-delete{
        font-size: 18px !important;
        color:rgb(243, 143, 130);
    }
    .el-input>>> .el-textarea__inner{
        font-size:18px!important;
    }
</style>
### 关于 `el-upload` 组件用于上图片实现预览功能的方法 #### 使用场景说明 为了满足前端开发中对于文件上的需求,特别是针对图片的上、展示以及管理需求,Element UI 提供了 `el-upload` 组件。该组件不仅支持基本的文件上操作,还提供了丰富的配置选项来增强用户体验。 #### 基本属性介绍 - **action**: 必填项,表示接收上请求的服务端接口地址[^1]。 - **list-type="picture-card"**: 设置此属性可以让上后的文件列表以卡片的形式呈现出来,每张图片都会被放置在一个独立的小方框内。 #### 事件处理机制 - **on-preview**: 当用户点击已上图片时触发,通常用来打开大图查看器或其他形式的媒体播放器。 - **on-remove**: 用户尝试从界面上移除某张特定图片时会调用此函数,可用于执行额外的数据清理工作或是向服务器发送删除指令。 #### 解决方案中的不足之处 尽管上述方式能够很好地完成大部分简单的图片任务,但在实际项目应用过程中可能会遇到一些局限性,比如无法灵活调整HTTP头信息(如加入认证令牌),这使得某些情况下难以直接利用默认行为与受保护资源交互[^2]。 #### 自定义解决方案建议 考虑到这些潜在的问题,在构建更加复杂的业务逻辑时,推荐采用更高级别的封装策略——创建一个通用型的上控件作为子模块重复使用。通过这种方式不仅可以简化代码结构,还能更好地适应多变的应用环境要求[^3]。 ```html <template> <div class="upload-demo"> <!-- 定义上区域 --> <el-upload :action="uploadUrl" list-type="picture-card" :file-list="imageList" @preview="handlePictureCardPreview" @remove="handleRemove" > <i class="el-icon-plus"></i> </el-upload> <!-- 查看大图对话框 --> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt /> </el-dialog> </div> </template> <script> export default { data() { return { uploadUrl: 'https://jsonplaceholder.typicode.com/posts/', // 替换成真实的API URL imageList: [], // 存储当前选中的图片数组 dialogImageUrl: '', // 大图链接 dialogVisible: false, // 控制弹窗显示状态 }; }, methods: { handleRemove(file) { console.log('正在移除:', file); this.imageList = this.imageList.filter(item => item.uid !== file.uid); // 更新本地缓存 }, handlePictureCardPreview(file) { this.dialogImageUrl = file.url; this.dialogVisible = true; // 显示大图 } } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值