[sgUpload] カスタム アップロード コンポーネント、アップロード フォルダーとそのサブフォルダー ファイルをサポート、バッチ アップロード、バッチ アップロードは右下隅のアップロード トレイに表示され、Base64image へのローカル アップロード画像変換をサポート

特性:

  1. ファイルとフォルダーのバッチアップロードをサポート
  2. カスタマイズ可能なヘッダー
  3. カスタマイズ可能なフィルターのアップロード形式
  4. カスタマイズ可能なアップロード API インターフェース
  5. ファイルやフォルダーのドラッグとアップロードを可能にするドラッグ属性をサポートします。

sgソースコードをアップロードする

<template>
    <div :class="$options.name" :dragenter="isDragenter">
        <!-- 上传按钮_________________________________________________________ -->
        <!-- 上传文件 -->
        <el-upload ref="uploadFile" :show-file-list="false" :headers="headers" :accept="accept.toString()"
            :action="actionUrl" :before-upload="beforeUpload" :on-success="uploadSuccess" :on-error="uploadError">
        </el-upload>

        <!-- 上传文件夹 -->
        <el-upload ref="uploadFolder" :show-file-list="false" :headers="headers" :action="actionUrl"
            :before-upload="beforeUpload" :on-success="uploadSuccess" :on-error="uploadError" :on-exceed="exceed" multiple
            :drag="drag === '' || drag">
        </el-upload>
        <!-- _________________________________________________________ -->

        <!-- 上传托盘(右下角) -->
        <sgUploadTray v-model="showUploadTray" :data="uploadList" @stopUpload="stopUpload"
            @dragStart="disabledRectSelect = true" @dragEnd="disabledRectSelect = false"
            v-if="!(hideUploadTray === '' || hideUploadTray)" />
    </div>
</template>
<script>
import sgUploadTray from "@/vue/components/admin/sgUploadTray";
export default {
    name: 'sgUpload',
    components: { sgUploadTray },
    data() {
        return {
            // 上传----------------------------------------
            headers: { kkToken: localStorage.token, }, //获取token(注意仔细看后端接受token的字段名是不是叫做“token”)
            accept: `.${['png', 'jpg', 'jpeg', 'bmp', 'gif', 'svg'].join(',.')}`,//默认只支持图片格式上传
            actionUrl: `${this.$d.API_ROOT_URL}/customer/importCustomerData`,
            dur: 100,
            percent: 100,
            uploadList: [],
            showUploadTray: false,
            uploadFileBtn: null,//上传文件
            uploadFolderBtn: null,//上传文件夹
            isDragenter: false,//是否拖入
            leaveEvents: [
                'mouseenter',
                'mouseover',
                'mousemove',
                'mouseout',
                'blur',
                'visibilitychange',
            ],
            dragAreaDom: null,//拖拽放入区域
            isDragTrigger: false,//是否为拖拽触发上传
            // ----------------------------------------
        }
    },
    props: [
        "data", //上传可选参数
        "hideUploadTray",//不显示上传托盘
        "drag",//是否支持拖拽文件、文件夹或多个文件
    ],
    watch: {
        data: {
            handler(d) {
                if (d) {
                    d.headers && (this.headers = d.headers);
                    d.accept && (this.accept = d.accept);
                    d.actionUrl && (this.actionUrl = d.actionUrl);
                }
            }, deep: true, immediate: true,
        },
        drag: {
            handler(d) {
                if (d === '' || d) {
                    this.addEvents();
                } else {
                    this.removeEvents();
                }
            }, deep: true, immediate: true,
        },
    },
    mounted() {
        this.$nextTick(() => {
            this.uploadFileBtn = this.$refs.uploadFile.$children[0].$refs.input;
            this.uploadFolderBtn = this.$refs.uploadFolder.$children[0].$refs.input;
            this.uploadFolderBtn && (this.uploadFolderBtn.webkitdirectory = true);//让el-upload支持上传文件夹

            this.dragAreaDom = this.$refs.uploadFolder.$el.querySelector(`.el-upload-dragger`);
            this.dragAreaDom && this.dragAreaDom.addEventListener('drop', this.drop);
        })
    },
    destroyed() {
        this.removeEvents();
    },
    methods: {
        // 监听----------------------------------------
        addEvents(d) {
            this.removeEvents();
            addEventListener('dragenter', this.dragenter);
            this.leaveEvents.forEach(v => addEventListener(v, this.leave));
            this.dragAreaDom && this.dragAreaDom.addEventListener('drop', this.drop);
        },
        removeEvents(d) {
            removeEventListener('dragenter', this.dragenter);
            this.leaveEvents.forEach(v => removeEventListener(v, this.leave));
            this.dragAreaDom && this.dragAreaDom.removeEventListener('drop', this.drop);
        },
        dragenter(d) {
            this.isDragTrigger = true;
            this.isDragenter = true;
        },
        leave(d) {
            this.isDragenter = false;
        },
        drop(d) {
            // 触发拖拽上传
            this.uploadDragFiles(d, file => {
                file.isDragFile = true;
                this.beforeUpload(file)
            }, files => {
            });
        },
        // 循环获取拖拽过来的file----------------------------------------
        uploadDragFiles(e, uploadFunc, completeFunc) {
            let files = [], items = [].slice.call(e.dataTransfer.items);
            items.forEach((v, i) => {
                const webkitGetAsEntry = v.webkitGetAsEntry();
                eval(webkitGetAsEntry.isDirectory ? 'setfolder' : 'setfile')(webkitGetAsEntry);
            });

            // 处理文件夹
            function setfolder(webkitGetAsEntry) {
                webkitGetAsEntry.createReader().readEntries(entries => (entries.forEach(item => (item.isFile ? setfile(item) : setfolder(item)))));
            }

            // 处理文件
            function setfile(webkitGetAsEntry) {
                webkitGetAsEntry.file(file => {
                    uploadFunc && uploadFunc(file);
                    files.push(file);
                });
            }
            completeFunc && completeFunc(files);
        },
        // 上传按钮触发----------------------------------------
        triggerUploadFile(d) {
            this.isDragTrigger = false;
            this.uploadFileBtn && this.uploadFileBtn.click();
        },
        triggerUploadFolder(d) {
            this.isDragTrigger = false;
            this.uploadFolderBtn && this.uploadFolderBtn.click();
        },
        // 上传文件----------------------------------------------------------------
        showFakeLoading(file) {
            file.raw && (file = file.raw);
            file = this.uploadList.find(v => v.uid == file.uid);
            clearInterval(file.interval);
            file.percent = 0;
            file.interval = setInterval(() => {
                file.percent >= 99 ? this.hideFakeLoading(file) : file.percent++;
            }, this.dur);
        },
        hideFakeLoading(file, { type, tip, color } = {}) {
            file.raw && (file = file.raw);
            file = this.uploadList.find(v => v.uid == file.uid);
            clearInterval(file.interval);
            switch (type) {
                case 'error':
                    file.percent = 0;
                    break;
                case 'success':
                default:
                    file.percent = 100;
            }
            type && (file.type = type);
            tip && (file.tip = tip);
            color && (file.color = color);
        },
        exceed(file, fileList) {
            this.$message.error("上传文件数量太大,分散上传吧!");
        },
        stopUpload(d) {
            this.$refs.uploadFolder.abort();
            //console.log(`取消上传`, d);
        },
        //文件上传之前
        beforeUpload(file) {
            if ((this.drag === '' || this.drag) && this.isDragTrigger) {
                if (!file.isDragFile) return;//拖拽模式下,如果不是原生js捕获到的拖拽文件,就不进入上传队列
            }
            file.uid || (file.uid = this.$g.UUID());
            this.uploadList.unshift({
                interval: null,
                uid: file.uid,
                percent: 0,//加载进度
                name: file.name,
                size: file.size,
                type: file.type,
                webkitRelativePath: file.webkitRelativePath,
                type: '',
                tip: '',
                color: '',
            });
            this.showUploadTray = true;
            // 判断是不是特定的格式________________________
            let isFile = this.accept === '*' ? true : this.accept.includes(file.name.toLocaleLowerCase().split(".").pop());
            const maxSize = 50; //限制大小
            const isAllowSize = file.size / 1024 / 1024 <= maxSize;
            isFile || this.$message.error("上传文件只能是" + this.accept + "格式");
            isAllowSize || this.$message.error("上传文件大小不能超过" + maxSize + "MB");
            let allowUpload = isFile && isAllowSize;
            if (allowUpload) {
                this.showFakeLoading(file);
                this.$g.file2Base64Image(file, d => this.$emit(`resultBase64Image`, d));
                this.$emit(`beforeUpload`, file);
            } else {
                this.hideFakeLoading(file, { type: 'error', tip: "上传失败", color: "red" });
            }
            return allowUpload; //若返回false则停止上传
        },
        //上传成功
        uploadSuccess(response, file, fileList) {
            if ((this.drag === '' || this.drag) && this.isDragTrigger) {
                if (!file.isDragFile) return;//拖拽模式下,如果不是原生js捕获到的拖拽文件,就不进入上传队列
            }
            if (response.data && response.data.key) {
                // 下载失败原因的描述文件
                this.$d.customer_downloadImportCustomerExcel({ key: response.data.key }, {
                    s: (d) => {
                        this.$emit(`error`, response, file);
                        this.hideFakeLoading(file, { type: 'error', tip: "上传失败", color: "red" });
                        this.$g.downloadFile(d, `${file.name}-上传失败原因`, '.xls');
                        this.$message.error(`${file.name}-上传失败,请查看失败原因`);
                        // this.initList();//刷新列表
                        //console.log('上传失败', response, file, fileList);
                    }
                });
            } else if (response.success) {
                this.$emit(`success`, response, file);
                // 上传成功了
                this.hideFakeLoading(file, { type: 'success', tip: "上传成功", color: "green" });
                this.$message.success(`“${file.name}上传成功`);
                // this.initList();//刷新列表
                //console.log('上传成功', response, file, fileList);
            } else {
                this.$emit(`error`, response, file);
                // 其他失败原因
                this.hideFakeLoading(file, { type: 'error', tip: "上传失败", color: "red" });
                // this.$message.error(response.msg);
                //console.log('上传失败', response, file, fileList);
            }
        },
        //上传失败
        uploadError(err, file, fileList) {
            if ((this.drag === '' || this.drag) && this.isDragTrigger) {
                if (!file.isDragFile) return;//拖拽模式下,如果不是原生js捕获到的拖拽文件,就不进入上传队列
            }
            this.$emit(`error`, err, file);
            this.hideFakeLoading(file, { type: 'error', tip: "上传失败", color: "red" });
            this.$message.error("上传失败");
            //console.log('上传失败', err, file, fileList);
        },
    }
};
</script>
<style lang="scss">
.sgUpload {
    width: 0;
    height: 0;

    .el-upload-dragger {
        z-index: 999999; //根据情况自己拿捏
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        display: none;
        background-color: #ffffff99;

        &::after {
            content: "拖拽文件到此处";
            position: absolute;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #743a72;
            font-size: 18px;
            font-weight: bold;
            line-height: 1.2;
        }
    }

    &[dragenter] .el-upload-dragger {
        display: block;
        border-color: #743a72;

        &.is-dragover {
            background-color: #743a7222;

            &::after {
                content: "松掉鼠标上传文件";
            }
        }
    }
}
</style>

応用

<template>
    <div>
        <div style="width:300px;height:300px;position: relative;">
            <img :src="src" style="width:100%;height:100%">
            <!-- 上传组件 -->
            <sgUpload drag ref="sgUpload" :data="{
                accept: `*`,
                actionUrl: `${$d.API_ROOT_URL}/customer/importCustomerData`,
            }" @resultBase64Image="resultBase64Image" @success="uploadSuccess" @error="uploadError" hideUploadTray />
        </div>
        <el-button type="primary" icon="el-icon-upload2" @click="d => $refs.sgUpload.triggerUploadFile()">上传</el-button>

    </div>
</template>
    
<script>
import sgUpload from "@/vue/components/admin/sgUpload";
export default {
    components: {
        sgUpload,
    },
    data() {
        return {
            src: '',
        }
    },
    methods: {
        resultBase64Image(d, f) {
            console.log(this.$options.name)
            this.src = d;
        },
        uploadSuccess(d, f) { }, uploadError(d, f) { },
    }
};
</script>

元のソースのel-upload は、アップロード フォルダー (バッチ アップロード ファイル) を実装し、アップロード ポップアップ ウィンドウを呼び出すためのボタン トリガー click() をサポートします (el-upload コンポーネントの作成を使用できるように、el-upload ノードの作成を減らすのに役立ちます)複数の場所に)_あなたの最愛の強い兄弟のブログ - CSDN ブログ/el-upload でフォルダーのアップロードをサポートさせてください。[sgUploadTray] アップロード トレイ カスタム コンポーネント、アップロード リストの進行状況をリアルタイムで表示できます_愛する強い兄貴のブログ - CSDN ブログ。[sgUploadTray] アップロード トレイ カスタム コンポーネント。アップロード リストの進行状況をリアルタイムで表示できます。el-upload はフォルダーのアップロード (ファイルのバッチアップロード) を実装します。キーコードは次のとおりです。sgUploadTray コンポーネントはここにあります。https://blog.csdn.net/qq_37860634/article/details/131721594

おすすめ

転載: blog.csdn.net/qq_37860634/article/details/131953758