vue element-ui upload 图片文件上传封装简化

element upload提供的功能很强大,但在使用的时候,有太多参数,和事件回调需要处理,不便于重复使用,每次都还弄晕了,为了便于使用,我将Upload针对于图片上传的功能,进行了一个封装处理,所有的回调都在插件里面进行处理了,使用只需要加一个标签就可以了,支持多文件上传,删除,预览,回显,文件大小限制,文件类型限制,自定义上传方法等各种参数,有需要的朋友可以看看,如果有更好的方法和意见,欢迎留言讨论。

项目GitHub地址:https://github.com/dingh123/dh-plugin/tree/master/UploadImage

UploadImage

基于ElementUI二次封装的图片上传组件,支持多文件上传,直接使用v-model取值回显

使用方式

script 中引用组件

import UploadImage from '@/components/UploadImage/index.vue';
export default {
     
    components: {
     UploadImage}
}

template 中使用组件

<upload-image ref="uploadImage" v-model="formData.image" :limit="6" :multiple="true" description="建议上传600x600的图片,只能上传jpg/png/gif文件" />

如果动态设置回显,需要手动触发一下watchValue方法

this.formData.image = res.image;

this.$nextTick(() => {
     
    this.$refs.uploadImage.watchValue();
});

属性说明

属性名 类型 默认值 说明
multiple Boolean false 是否支持多选
data Object - 上传时附带的额外参数
showFileList Boolean true 是否显示已上传文件列表
limit Number - 最大允许上传个数
name String file 设定文件域的字段名
accept String image/jpeg, image/png, image/gif 接受上传的文件类型
description String - 文件上传描述
size Number 5 * 1024 文件大小限制,单位KB,默认5MB
httpRequest Function - 自定义上传方法

组件里面设置上传的方法

1、【默认上传】这个方法是设置组件默认上传的方法,避免每次使用时候都需要写一个上传方法;

uploadImgRequest(f) {
     
   let param = new FormData(); //创建form对象
    param.append('file', f.file); //通过append向form对象添加数据
    uploadImg(param)
        .then(res => {
     
            f.onSuccess(res);
        })
        .catch(() => {
     
            f.onError();
        });
},

2、【自定义上传】支持默认上传的同时也支持自定义上传方法,httpRequest

<template>
    <upload-image
        class="icon-image"
        ref="uploadFavicon"
        v-model="favicon"
        :limit="1"
        accept="image/x-icon"
        :http-request="uploadRequestIcon"
    />
template>

<script>
import UploadImage from '@/components/UploadImage/index.vue';
import {
       uploadIcon } from '@/api';
export default {
      
    components: {
       UploadImage },
    methods: {
      
        /**
         * 自定义上传方法,icon
         */
        uploadRequestIcon(f) {
      
            let param = new FormData(); //创建form对象
            param.append('file', f.file); //通过append向form对象添加数据

            uploadIcon(param)
                .then(res => {
      
                    f.onSuccess(res);
                })
                .catch(() => {
      
                    f.onError();
                });
        },
    },
};
script>

最后封装源码

UploadImage.vue

<template>
    <div>
        <el-upload
            ref="elUpload"
            action="#"
            list-type="picture-card"
            :data="data"
            :multiple="multiple"
            :limit="limit"
            :fileList="fileList"
            :show-file-list="showFileList"
            :name="name"
            :accept="accept"
            :before-upload="beforeUpload"
            :on-preview="handlePictureCardPreview"
            :on-success="handleImageSuccess"
            :on-remove="handleRemove"
            :on-exceed="handleExceed"
            class="upload-image"
            :class="{ 'hide-upload': hideUpload }"
            :http-request="httpRequestMain"
        >
            <div class="upload-tip">
                <i class="el-icon-plus">i>
                <div class="el-upload__tip" v-if="description">
                    {
    { description }}
                div>
            div>
        el-upload>

        <el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="viewImageUrl" />
    div>
template>
<script>
import {
       uploadImg } from '@/api';
import emitter from 'element-ui/src/mixins/emitter';
import ElImageViewer from 'element-ui/packages/image/src/image-viewer';

export default {
      
    name: 'UploadImage',
    mixins: [emitter],
    components: {
      
        ElImageViewer,
    },
    props: {
      
        value: {
      
            type: String,
            default: '',
        },
        // 是否支持多选
        multiple: {
      
            type: Boolean,
            default: false,
        },
        // 上传时附带的额外参数
        data: {
      
            type: Object,
        },
        // 是否显示已上传文件列表
        showFileList: {
      
            type: Boolean,
            default: true,
        },
        // 最大允许上传个数
        limit: {
      
            type: Number,
        },
        // 设定文件域的字段名
        name: {
      
            type: String,
            default: 'file',
        },
        // 接受上传的文件类型
        accept: {
      
            type: String,
            default: 'image/jpeg, image/png, image/gif',
        },
        // 文件上传描述
        description: {
      
            type: String,
            default: '',
            // default: '请上传图片,只能上传jpg/png/gif文件',
        },
        validateEvent: {
      
            type: Boolean,
            default: true,
        },
        // 文件大小限制,单位KB,默认5MB
        size: {
      
            type: Number,
            default: 5 * 1024,
        },
        // 自定义文件上传方法
        httpRequest: {
      
            type: Function,
        },
    },
    data() {
      
        return {
      
            tempUrl: '',
            hideUpload: false,
            fileList: [],
            showViewer: false,
            viewImageUrl: [],
        };
    },
    inject: {
      
        elForm: {
      
            default: '',
        },
        elFormItem: {
      
            default: '',
        },
    },
    created() {
      
        this.watchValue();
    },
    watch: {
      
        value(val) {
      
            // this.watchValue();
            // console.log(val);
        },
    },
    methods: {
      
        httpRequestMain(f) {
      
            this.httpRequest ? this.httpRequest(f) : this.uploadImgRequest(f);
        },
        watchValue() {
      
            let valueArray = this.value ? this.value.split(',') : [];
            this.fileList = valueArray.map(item => {
      
                return {
      
                    name: item,
                    url: item,
                };
            });
            this.update();
        },
        uploadImgRequest(f) {
      
            let param = new FormData(); //创建form对象
            param.append('file', f.file); //通过append向form对象添加数据
            uploadImg(param)
                .then(res => {
      
                    f.onSuccess(res);
                })
                .catch(() => {
      
                    f.onError();
                });
        },
        update() {
      
            let valueArray = this.value ? this.value.split(',') : [];
            if (valueArray.length >= this.limit) {
      
                this.hideUpload = true;
            } else {
      
                this.hideUpload = false;
            }
        },
        emitInput(value) {
      
            this.$emit('input', value);
            this.dispatch('ElFormItem', 'el.form.change', value);
            this.$nextTick(() => {
      
                this.update();
            });
        },
        beforeUpload(file) {
      
            const fileMax = file.size / 1024 < this.size;

            if (!fileMax) {
      
                this.$message.error(`上传图片大小不能超过 ${
        this.renderSize(this.size / 1024)}!`);
            }
            return !!fileMax;
        },
        handlePictureCardPreview(file) {
      
            this.viewImageUrl = [file.url];
            this.showViewer = true;
        },
        closeViewer() {
      
            this.showViewer = false;
        },
        handleRemove(file, fileList) {
      
            const fileArray = fileList.map(item => {
      
                return item.response.url;
            });
            this.emitInput(fileArray.join(','));
        },
        handleImageSuccess(res, file, fileList) {
      
            file.url = res.url;
            this.emitInput(this.value ? this.value + ',' + res.url : res.url);
        },
        handleExceed() {
      
            this.$message.error(`最多上传${
        this.limit}张图片`);
        },
        clearFiles() {
      
            this.$refs.elUpload.clearFiles();
        },
        renderSize(value) {
      
            if (null == value || value == '') {
      
                return '0 Bytes';
            }
            let unitArr = new Array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
            let index = 0;
            let srcsize = parseFloat(value);
            index = Math.floor(Math.log(srcsize) / Math.log(1024));
            let size = srcsize / Math.pow(1024, index);
            size = size.toFixed(2); //保留的小数位数
            return size + unitArr[index];
        },
    },
};
script>

<style lang="scss" scoped>
/deep/ .el-upload-list--picture-card {
      
    display: flex;
    /deep/ .el-upload-list__item {
      
        margin: 0;
    }
}
.hide-upload /deep/ .el-upload--picture-card {
      
    display: none;
}
.upload-tip {
      
    height: 100%;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    padding: 10px;
}
.el-upload__tip {
      
    line-height: 20px;
    margin-top: 10px;
}
style>

你可能感兴趣的:(js,vue.js,javascript,elementui,upload)