美文网首页
对element-ui上传组件Upload 再简化

对element-ui上传组件Upload 再简化

作者: 谢_ffd1 | 来源:发表于2020-09-13 14:28 被阅读0次

    重置组件目的

    对Upload 上传组件在简化的目的是对文件上传前的限制都统一到组件中去完成不在繁琐的每个去写,同时增加上传后图片的大图预览,音频试听,视频观看等。

    组件代码(简化后代码基本兼容原有使用方法除了slot="file"外)

    <template>
        <div>
            <el-upload :class="(listType=='single' && !$slots.default)? 'avatar-uploader':''" :action="url"
                       :headers="headers" :data="data" :multiple="multiple" :name="name" :drag="drag"
                       :with-credentials="withCredentials" :disabled="disabled" :limit="limit"
                       :show-file-list="isShowFileList" :list-type="customListType" :fileList="fileList"
                       :auto-upload="autoUpload" :http-request="httpRequest"
                       :before-upload="handleBeforeUpload"
                       :on-success="handleSuccess"
                       :on-exceed="handleExceed"
                       :on-error="handleError"
                       :on-preview="handlePreview"
                       :on-change="handleChange"
                       :on-progress="handleProgress"
                       :before-remove="handleBeforeRemove"
                       :on-remove="handleRemove">
                <template v-if="drag && !$slots.default">
                    <i class="el-icon-upload"></i>
                    <div class="el-upload__text">
                        {{$t('pages.common.dragFilesHere')}}<em>{{$t('pages.common.clickUpload')}}</em></div>
                </template>
                <!--单图片上传-->
                <template v-else-if="listType=='single' && !$slots.default">
                    <el-image v-if="imageUrl" :src="imageUrl" class="avatar"></el-image>
                    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                </template>
                <template v-else-if="(listType=='picture-card' || listType=='video') && !$slots.default">
                    <i class="el-icon-plus"></i>
                </template>
                <template v-else-if="!$slots.default">
                    <el-button size="small" type="primary">{{$t('pages.common.clickUpload')}}</el-button>
                </template>
                <slot></slot>
                <template slot="file" slot-scope="{file}" v-if="listType=='video'">
                    <el-progress v-if="file.status === 'uploading'" type="circle"
                                 :stroke-width="6"
                                 :percentage="parsePercentage(file.percentage)">
                    </el-progress>
                    <div class="el-upload-list__item-thumbnail" v-if="file">
                        <video class="el-upload-list__item-thumbnail" :src="file.url"></video>
                        <span class="el-upload-list__item-actions">
                          <span class="el-upload-list__item-preview"
                                @click="handlePreview(file)">
                            <i class="sx-icon-video" style="font-size: 19px"></i>
                          </span>
                          <span class="el-upload-list__item-delete">
                            <i class="el-icon-delete" @click="handleRemove(file,fileList)"></i>
                          </span>
                        </span>
                    </div>
                </template>
            </el-upload>
            <!-- 查看大图   -->
            <el-dialog title="大图预览" :visible.sync="dialogImageVisible" append-to-body>
                <img width="100%" :src="dialogImageUrl" alt="大图">
            </el-dialog>
            <!--观看视频-->
            <el-dialog title="赏析视频" :visible.sync="dialogVideoVisible" @close="handlePause" append-to-body>
                <video ref="video" style="width: 100%; height: 100%; display: block; outline: none;" :src="dialogVideoUrl"
                       controls
                       autoplay></video>
            </el-dialog>
            <!--试听音频-->
            <el-dialog title="试听音频" :visible.sync="dialogAudioVisible" @close="handlePause" append-to-body>
                <audio ref="audio" style="width: 100%; height: 50px; display: block; outline: none;" :src="dialogAudioUrl"
                       controls
                       autoplay></audio>
            </el-dialog>
        </div>
    </template>
    
    <script>
        import isEqual from 'lodash/isEqual'
    
        /*自定义上传 - element-ui上传再封装*/
        export default {
            name: "ElUploadCustom",
            data() {
                return {
                    dialogImageVisible: false,
                    dialogImageUrl: null,
                    dialogVideoVisible: false,
                    dialogVideoUrl: null,
                    dialogAudioVisible: false,
                    dialogAudioUrl: null,
                    imageUrl: ''
                }
            },
            model: {
                prop: 'value',
                event: 'change'
            },
            props: {
               value:{
                    type: Array,
                    default() {
                        return [];
                    }
                },
                action: {
                    type: String,
                    required: true
                },
                headers: {
                    type: Object,
                    default() {
                        return {};
                    }
                },
                data: Object,
                multiple: Boolean,
                name: {
                    type: String,
                    default: 'file'
                },
                drag: Boolean,
                accept: String,
                flieSize: Number,
                withCredentials: Boolean,
                showFileList: {
                    type: Boolean,
                    default: true
                },
                listType: {
                    type: String,
                    default: 'text' // text,picture,picture-card single:单图片上传 video:上传视频 audio: 上传音频
                },
                disabled: Boolean,
                limit: Number,
                fileList: {
                    type: Array,
                    default() {
                        return [];
                    }
                },
                autoUpload: {
                    type: Boolean,
                    default: true
                },
                httpRequest: Function,
                beforeUpload: Function,
                beforeRemove: Function,
                onRemove: Function,
                onChange: Function,
                onPreview: Function,
                onSuccess: Function,
                onProgress: Function,
                onError: Function,
                onExceed: Function
            },
            watch: {
                fileList: {
                    handler: function (val) {
                        if (this.listType == 'single') {
                            this.imageUrl = val.length ? val[0].url : '';
                        }
                    },
                    immediate: true
                }
            },
            computed: {
                url() {
                    if (/^((https|http|ftp|rtsp|mms)?:\/\/)[^\s]+/.test(this.action)) {
                        return this.action
                    } else {
                        if (typeof this.httpRequest == "function") {
                            return '#';
                        } else {
                            return this.$http.defaults.baseURL + this.action;
                        }
                    }
                },
                isShowFileList() {
                    if (this.listType == 'single') {
                        return false;
                    } else {
                        return this.showFileList;
                    }
                },
                customListType() {
                    if (this.listType == 'single' || this.listType == 'audio') {
                        return 'text';
                    } else if (this.listType == 'video') {
                        return 'picture-card';
                    } else {
                        return this.listType
                    }
                }
            },
            methods: {
                //文件上传前事件
                handleBeforeUpload(file) {
                    if (this.beforeUpload) {
                        return this.beforeUpload(file);
                    } else {
                        //判断文件类型
                        const typeLimit = this.accept ? this.accept.split(',').includes(file.type) : true;
                        //判断文件大小
                        const sizeLinit = this.flieSize ? file.size / 1024 < this.flieSize : true;
                        if (!typeLimit) {
                            this.$message.error(this.$t('pages.common.uploadFileType', {type: this.accept}));
                        }
                        if (!sizeLinit) {
                            let flieSize = this.flieSize > 1024 ? parseInt(this.flieSize / 1024) + 'M' + this.flieSize % 1024 : this.flieSize;
                            this.$message.error(this.$t('pages.common.uploadFileSize', {size: flieSize}));
                        }
                        return typeLimit && sizeLinit;
                    }
                },
                //文件上传超出限制事件
                handleExceed(files, fileList) {
                    if (this.onExceed) {
                        this.onExceed(files, fileList);
                    } else {
                        this.$message.error(this.$t('pages.common.uploadFileNumber', {number: this.limit}))
                    }
                },
                //上传进度事件
                handleProgress(event, file, fileList) {
                    if (this.onProgress) {
                        this.onProgress(event, file, fileList)
                    }
                },
                //上传成功事件
                handleSuccess(res, file, fileList) {
                    if (this.onSuccess) {
                        this.onSuccess(res, file, fileList);
                    } else {
                        if (!res.code) {
                            if (this.listType == 'single') {
                                file.url = res.data;
                                this.imageUrl = res.data;
                                this.$emit('change', [file]);
                            } else {
                                fileList.forEach(item => {
                                    if (isEqual(item, file)) {
                                        item.url = res.data
                                    }
                                });
                                this.$emit('change', fileList);
                            }
                        } else {
                            this.handleRemove(file, fileList);
                            this.$message.error(this.$t('pages.common.uploadFileError'));
                        }
                    }
                },
                //预览事件
                handlePreview(file) {
                    if (this.onPreview) {
                        this.onPreview(file);
                    } else {
                        if (this.listType == 'audio') {
                            this.dialogAudioUrl = file.url;
                            this.dialogAudioVisible = true;
                            if (this.$refs.video) {
                                this.$refs.video.remove()
                            }
                        } else if (this.listType == 'video') {
                            this.dialogVideoUrl = file.url;
                            this.dialogVideoVisible = true;
                            if (this.$refs.audio) {
                                this.$refs.audio.remove()
                            }
                        } else {
                            //没有提供文件类型就下载判定
                            if (!file.raw) {
                                let xhr = new XMLHttpRequest();
                                xhr.open("GET", file.url, true);
                                xhr.responseType = "blob";
                                xhr.onload = () => {
                                    file.raw = xhr.response
                                    //判断当前点击文件是否为图片类型 是显示大图预览
                                    if (['image/png', 'image/jpeg', 'image/gif', 'application/x-jpg', 'application/x-png'].includes(file.raw.type)) {
                                        this.dialogImageUrl = file.url;
                                        this.dialogImageVisible = true;
                                    }
                                    //判断当前点击文件是否为音频类型 是显示试听音频
                                    if (['audio/mp3'].includes(file.raw.type)) {
                                        this.dialogAudioUrl = file.url;
                                        this.dialogAudioVisible = true;
                                    }
                                    //判断当前点击文件是否为视频类型 是显示赏析视频
                                    if (['video/mp4'].includes(file.raw.type)) {
                                        this.dialogVideoUrl = file.url;
                                        this.dialogVideoVisible = true;
                                    }
                                };
                                xhr.send();
                            } else {
                                //判断当前点击文件是否为图片类型 是显示大图预览
                                if (['image/png', 'image/jpeg', 'image/gif'].includes(file.raw.type)) {
                                    this.dialogImageUrl = file.url;
                                    this.dialogImageVisible = true;
                                }
                                //判断当前点击文件是否为音频类型 是显示试听音频
                                if (['audio/mp3'].includes(file.raw.type)) {
                                    this.dialogAudioUrl = file.url;
                                    this.dialogAudioVisible = true;
                                }
                                //判断当前点击文件是否为视频类型 是显示赏析视频
                                if (['video/mp4'].includes(file.raw.type)) {
                                    this.dialogVideoUrl = file.url;
                                    this.dialogVideoVisible = true;
                                }
                            }
                        }
                    }
                },
                //上传失败事件
                handleError(err, file, fileList) {
                    if (this.onError) {
                        this.onError(err, file, fileList);
                    } else {
                        this.handleRemove(file, fileList);
                        this.$message.error(this.$t('pages.common.uploadFileError'));
                    }
                },
                //文件移除前事件
                handleBeforeRemove(file, fileList) {
                    if (this.beforeRemove) {
                        this.beforeRemove(file, fileList);
                    }
    
                },
                //删除事件
                handleRemove(file, fileList) {
                    if (this.onRemove) {
                        this.onRemove(file, fileList);
                    } else {
                        let index = fileList.findIndex(item => item.uid == file.uid);
                        if (index != -1) {
                            fileList.splice(index, 1);
                        }
                        this.$emit('change', fileList);
                    }
                },
                //文件状态改变事件
                handleChange(file, fileList) {
                    if (this.onChange) {
                        this.onChange(file, fileList);
                    }
                },
                //暂停播放音频视频
                handlePause() {
                    if (this.$refs.audio) {
                        this.$refs.audio.pause();
                        this.dialogAudioVisible = false;
                    }
                    if (this.$refs.video) {
                        this.$refs.video.pause();
                        this.dialogVideoVisible = false;
                    }
                },
                //进度百分比
                parsePercentage(val) {
                    return parseInt(val, 10);
                },
            },
            created() {
            }
        }
    </script>
    
    <style scoped>
        .avatar-uploader >>> .el-upload {
            border: 1px dashed #d9d9d9;
            border-radius: 6px;
            cursor: pointer;
            position: relative;
            overflow: hidden;
        }
    
        .avatar-uploader .el-upload:hover {
            border-color: #409EFF;
        }
    
        .avatar-uploader-icon {
            font-size: 28px;
            color: #8c939d;
            width: 178px;
            height: 178px;
            line-height: 178px;
            text-align: center;
        }
    
        .avatar {
            width: 178px;
            height: 178px;
            display: block;
        }
    </style>
    
    

    组件使用

    <template>
      //@getData获取上传的文件列表  :flie-size 限制文件上传大小(如下限制500kb)不填无限制 accept限制文件上传类型(如下只能上传png和jpg图片)不填无限制
      <el-upload-custom v-model="picurls"  list-type="picture-card" :file-list="picurls"
                                          action="/SXBS-INFORMATION/file/uploadFileUsingOriginalFilename"
                                          :flie-size="500" accept="image/png,image/jpeg">
                        </el-upload-custom>
    </template>
    <script>
      export default {
        methods: {
        
       
        },
        data() {
          return {
              picurls:[]  
          };
        },
        mounted(){
         
        },
        created() {
           
        }
      }
    </script>
    

    相关文章

      网友评论

          本文标题:对element-ui上传组件Upload 再简化

          本文链接:https://www.haomeiwen.com/subject/gdinektx.html