vue实现复制粘贴图片上传

最近业务提了个需求 要求在原有的图片上传基础上用微信QQ等工具实现截图,然后粘贴实现上传

实现这个需求并不难,可以使用el-input的paste来实现,下面一起来看代码

<template>
    <el-dialog append-to-body width="500px" :visible="visible" title="xx弹窗" :close-on-click-modal="false" @open="openDialog" @close="closeDialog('ruleForm')">
        <el-form :model="formModel" :rules="rules" ref="ruleForm" class="demo-ruleForm" label-width="85px">
            <el-form-item label="选择" prop="type_no_arr">
                <el-select clearable multiple collapse-tags filterable class="input-layout" v-model="formModel.type_no_arr">
                    <el-option v-for="item in statusArr" :value="item.type_no" :label="item.name" :key="item.id"> </el-option>
                </el-select>
            </el-form-item>
            <el-form-item label="上传图片" prop="apply_image" v-loading="dataLoading">
                <el-input
                    class="mb10 input-layout"
                    type="textarea"
                    :rows="2"
                    placeholder="粘贴图片即可上传"
                    v-model="uploadImg"
                    @paste.native="handlePaste"
                >
                </el-input>
                <el-upload
                    :file-list="srcList"
                    :action="imageUrl"
                    :on-success="uploadSuccess.bind(null, srcList)"
                    :class="{ hideUpload: srcList.length >= 5 }"
                    accept=".png,.jpg,.jpeg.gif"
                    list-type="picture-card"
                >
                    <i slot="default" class="iconfont iconda_jiahao fs24"></i>
                    <div slot="file" slot-scope="{ file }">
                        <el-image fit="cover" :src="file.url"></el-image>
                        <span class="el-upload-list__item-actions">
                            <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file.url)">
                                <i class="iconfont iconzhong_chakan"></i>
                            </span>
                            <span class="el-upload-list__item-delete" @click="uploadRemove(srcList, file.url)">
                                <i class="iconfont iconzhong_lajitong"></i>
                            </span>
                        </span>
                    </div>
                </el-upload>
                <el-image-viewer class="modal-image" title="图片预览" :url-list="[dialogImageUrl]" v-if="dialogImgVisible" :on-close="closePreview"></el-image-viewer>
            </el-form-item>
        </el-form>
        <div slot="footer">
            <el-button type="primary" @click="submit('ruleForm')" :loading="loading">提交</el-button>
        </div>
    </el-dialog>
</template>

<script>
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
import axios from 'axios'

export default {
    name: 'dialog',
    components: {
        ElImageViewer,
    },
    props: {
        visible: Boolean,
        data: {
            type: Object,
            default: () => ({}),
        },
        userObj: {
            type: Object,
            default: () => ({}),
        },
    },
    watch: {
        visible(v) {
            if (v) {
                //
            }
        }
    },
    data() {
        return {
            loading: false,
            formModel: {
                ucode: '',
                type_no_arr: '',
                apply_image: [],
            },
            statusArr: [],
            rules: {
                type_no_arr: [{ required: true, message: '请选择', trigger: 'blur' }],
            },
            imageUrl: process.env.FILE_URL + '/api/files/upload',
            hideUpload: false,
            dialogImageUrl: '',
            dialogVisible: false,
            disabled: false,
            srcList: [],
            statusArr: [],
            dialogImgVisible: false,
            uploadImg: '',
            imgFile: '',
            dataLoading: false
        }
    },
    methods: {
        handlePaste(value) {
            this.dataLoading = true
            let file = value.clipboardData.items[0]
            if (file.type.includes('image')) {
                let imgFile = file.getAsFile()
                const formData = new FormData()
                formData.append('file', imgFile)
                const axiosInstance = axios.create({ withCredentials: false })
                axiosInstance({
                    method: 'post',
                    url: process.env.FILE_URL + '/api/files/upload', // 上传地址,视情况更换
                    data: formData,
                    })
                    .then(res => {
                        // 调用成功回调
                        console.log('粘贴图片返回的数据=', res.data)
                        this.dataLoading = false
                        this.formModel.apply_image.push(res.data.data.file_id)
                        this.srcList.push({
                            url: process.env.FILE_URL + '/api/files/show/' + res.data.data.file_id,
                            file_id: res.data.data.file_id,
                        })
                    })
                    .catch(function (err) {
                        this.dataLoading = false
                        console.log(err)
                        // 上传失败
                })
            }
        },
        uploadRemove(item, url, file_id) {
            this.srcList = item.filter((file) => file.url !== url)
            this.formModel.apply_image = []
            this.srcList.map((v) => {
                this.formModel.apply_image.push(v.file_id)
            })
        },
        closePreview() {
            this.dialogImgVisible = false
        },
        handlePictureCardPreview(url) {
            this.dialogImgVisible = true
            this.dialogImageUrl = url
        },
        uploadSuccess(response, file, fileList) {
            if (response.code !== 0) {
                this.$notify({
                    title: '错误',
                    type: 'error',
                    message: '上传失败',
                })
                return
            }
            this.formModel.apply_image.push(file.response.data.file_id)
            this.srcList.push({
                url: process.env.FILE_URL + '/**/**/**/' + file.response.data.file_id, // 服务器上传url
                file_id: file.response.data.file_id,
            })
        },
        openDialog() {
        },
        closeDialog(formName) {
            this.$emit('update:visible', false)
            this.$refs[formName].resetFields()
            this.srcList = []
        },
        submit(formName) {
            this.$refs[formName]
                .validate()
                .then((res) => {
                    this.loading = true
                    applyApplication(this.formModel)
                        .then((res) => {
                            this.$message({
                                message: '申请成功!',
                                type: 'success',
                                center: true,
                            })
                            setTimeout(() => {
                                this.closeDialog('ruleForm')
                                this.$emit('confirm', this.formModel.ucode)
                            }, 200)
                        })
                        .catch(() => {
                            this.$message({
                                message: '申请失败!',
                                type: 'error',
                                center: true,
                            })
                        })
                        .finally(() => {
                            this.loading = false
                        })
                })
                .catch(() => {})
        },
    },
}
</script>

<style scoped lang="scss">
.modal-image {
    top: 0;
    z-index: 99999 !important;
}
/deep/ .cover-upload {
    width: 100%;
    display: flex;
    justify-content: flex-start;
    align-items: center;

    .el-upload,
    .el-upload-dragger {
        width: 60px;
    }

    .el-upload--picture-card {
        width: 60px;
        height: 60px;
        box-sizing: border-box;
        border-style: solid;
    }

    .el-upload-list--picture-card {
        width: auto;
        ul,
        li {
            width: auto;
        }
    }
    .el-upload-dragger {
        height: 100%;
        border: transparent;
        background-color: #f5f5f5;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    &.hide-upload .el-upload--picture-card {
        display: none !important;
        text-align: left;
    }
}
.el-upload-list.el-upload-list--picture-card {
    .el-upload-list__item {
        width: 146px !important;
        height: 146px !important;
        margin-right: 13px;
        .el-image {
            width: 146px;
            height: 146px;
            border-radius: 4px;
        }
    }
}
.el-upload-list--picture-card .el-upload-list__item-actions span + span {
    margin-left: 0px;
}
/deep/ .hideUpload {
    .el-upload.el-upload--picture-card {
        display: none !important;
    }
    .el-upload-list__item {
        margin: 0;
        & > div {
            width: 60px;
            height: 60px;
        }
    }
}
</style>

效果如下:

猜你喜欢

转载自blog.csdn.net/weixin_42611825/article/details/128439049