上传 多张 单张 图片、视频

<template>
    <div class="file-box">
        <div class="file-list">
            <div class="item"
                 v-for="(item, index) in binaryFile"
                 :key="index"
                 :style="{ width: width, height: height }">
                <img @click="showImg(item.url)"
                     v-if="type == 'image'"
                     :src="item.url" />
                <video controls
                       v-else-if="type == 'video'"
                       :src="item.url" />
                <i v-if="!disabled && limit != 0"
                   @click="handleRemove(item, index)"
                   class="close el-icon-close"></i>
                <div v-if="item.loading"
                     class="loading"></div>
            </div>
            <div v-if="binaryFile.length < limit && !disabled"
                 class="file-btn"
                 @click="handleUpload"
                 :style="{ width: width, height: height }">
                <i class="el-icon-plus"
                   :style="{ lineHeight: `calc(${height} - 8px)` }"><span>{{ title }}</span></i>
            </div>
            <input ref="upload"
                   @change="handleUploadChange"
                   multiple="multiple"
                   type="file" />
        </div>
    </div>
</template>

<script>
    import { uploadFile } from '@/api/common';
    import { Message } from 'element-ui';

    export default
    {
        props:
        {
            title:
            {
                default: "",
                type: String
            },
            width:
            {
                default: "70px",
                type: String
            },
            height:
            {
                default: "70px",
                type: String
            },
            limit:
            {
                default: 1,
                type: Number
            },
            value:
            {
                default: "",
                type: [Array, String]
            },
            type:
            {
                default: "image",
                type: String
            }
        },
        inject:
        {
            elForm:
            {
                default: ''
            },
            elFormItem:
            {
                default: ''
            }
        },
        data()
        {
            return {
                fileList: [],
                disabled: false,
                binaryFile: [],
                is_one_loading: false
            }
        },
        computed:
        {
            isLoading()
            {
                let loading = true;
                for (let index = 0; index < this.binaryFile.length; index++)
                {
                    const element = this.binaryFile[index];
                    if (element.loading)
                    {
                        loading = false;
                    }
                }
                return loading;
            }
        },
        watch:
        {
            binaryFile:
            {
                handler()
                {
                    if (this.binaryFile.length > 0)
                    {
                        if (this.limit == 1 && typeof this.value == 'string')
                        {
                            this.$emit("input", this.binaryFile[0].url);
                        }
                        else
                        {
                            this.$emit("input", this.binaryFile.map(item => item.url));
                        }
                    }
                    else
                    {
                        if (this.limit == 1 && typeof this.value == 'string' && this.value != '')
                        {
                            this.$emit("input", '');
                        }
                        else if (this.value.length > 0)
                        {
                            this.$emit("input", []);
                        }
                    }
                },
                deep: true
            },
            value:
            {
                immediate: true,
                deep: true,
                handler(v)
                {
                    if (this.limit == 1 && this.value != '' && this.binaryFile.length == 0 && !Array.isArray(this.value))
                    {
                        this.binaryFile = [{ url: this.value, loading: false }]
                    }
                    else if (Array.isArray(this.value) && this.value.length > 0 && this.binaryFile.length == 0)
                    {
                        this.binaryFile = this.value.map(item =>
                        {
                            return { url: item, loading: false }
                        })
                    }
                    else if (this.value.length == 0 && this.binaryFile.length != 0)
                    {
                        this.binaryFile = [];
                    }
                    console.log( this.binaryFile)
                }
            }
        },
        methods:
        {
            showImg(link)
            {
                this.$ImagePreview([{ thumbUrl: link, url: link }], 0);
            },
            handleUpload()
            {
                this.$refs['upload'].click()
            },
            /**
             * @param {Event} event
             */
            async handleUploadChange(event)
            {
                let fileList = event.target.files;
                let maxLength = this.limit - this.binaryFile.length;
                fileList.forEach((item, index) =>
                {
                    if (index >= maxLength) return;

                    this.$store.dispatch("updateUploadLimit", 1);
                    let url = window.URL.createObjectURL(item);
                    let fileIndex = this.binaryFile.length + index;
                    this.binaryFile.push({ loading: true, url, index: fileIndex });
                    this.uploadImage(item, fileIndex).then(({ index, url }) =>
                    {
                        this.binaryFile.forEach((item) =>
                        {
                            if (item.index == index)
                            {
                                item.loading = false;
                                item.url = url;
                            }
                        });
                    });
                });
                this.$refs["upload"].value = "";
            },
            /**
             * @param {File} file
             */
            async uploadImage(file, s)
            {
                let formData = new FormData();
                formData.append("file", file);
                var appId = sessionStorage.getItem("appCode") || "1";
                var appkey = appId == "2" ? "czzg" : appId == "3" ? "jlm" : "jdzg";
                formData.append("appKey", appkey);

                let { data } = await uploadFile(formData)
                    .then((r) => r)
                    .catch((e) => e);
                await this.$store.dispatch("updateUploadLimit", -1);

                if (data && data.code == 0)
                {
                    return { index: s, url: data.data.fileUrl };
                }
                else
                {
                    this.binaryFile.splice(s, 1);
                }
            },
            handleRemove(item, index)
            {
                if (this.binaryFile[index].loading)
                {
                    return Message.error("正在上传中, 请勿删除!");
                }
                this.binaryFile.splice(index, 1);
            },
        },
        mounted()
        {
            this.$nextTick(() =>
            {
                if (this.type == "image")
                {
                    this.$refs["upload"].setAttribute("accept", "image/*");
                }
                else if (this.type == "video")
                {
                    this.$refs["upload"].setAttribute("accept", "video/*");
                }
                this.disabled = (this.elForm || {}).disabled;
            });
        },
    };
</script>

<style lang="less"
       scoped>
    .file-list {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
    }

    .item,
    .file-btn {
        border: 1px solid #ccc;
        margin-right: 10px;
        margin-bottom: 10px;

        video,
        img {
            width: 100%;
            height: 100%;
        }

        i.el-icon-plus {
            display: block;
            font-size: 28px;
            color: #8c939d;
            text-align: center;
        }
    }

    .item {
        position: relative;

        i.close {
            position: absolute;
            top: -5px;
            right: -5px;
            background-color: red;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            text-align: center;
            line-height: 15px;
            font-size: 12px;
            cursor: pointer;
            color: #fff;
            z-index: 10;
        }
    }

    .file-btn {
        cursor: pointer;
    }

    input[type="file"] {
        display: none;
    }

    .el-icon-plus {
        span {
            vertical-align: bottom;
            font-size: 20px;
        }
    }

    .loading {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.5) url("../../image/loading.gif") no-repeat center center;
        background-size: 25px 25px;
    }
</style>

根据项目需要封装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq614756883

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值