广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >vue实现拖拽或点击上传图片
  • 1040
分享到

vue实现拖拽或点击上传图片

2024-04-02 19:04:59 1040人浏览 独家记忆
摘要

本文实例为大家分享了Vue实现拖拽或点击上传图片的具体代码,供大家参考,具体内容如下 一、预览图 二、实现 点击上传思路:将input的type设置为“file”类型即可上传文件

本文实例为大家分享了Vue实现拖拽或点击上传图片的具体代码,供大家参考,具体内容如下

一、预览图

二、实现

点击上传思路:将input的type设置为“file”类型即可上传文件。隐藏该input框,同时点击按钮时,调取该input的点击上传功能。剩下的就是CSS优化页面了。

拖拽上传思路:通过给拖拽框dropbox绑定拖拽事件,当组件销毁时解绑事件。在拖拽结束,通过event.dataTransfer.files获取上传的文件信息。然后在对文件进行上传服务器操作。

接下来请允许我简单介绍一下各个组件:

upload.vue封装了点击上传的逻辑,而进度条则没有做,后期可基于percent做参数继续完善进度条;uploadFORMDialog.vue是父盒子,即点击上传按钮后弹出的对话框,在该组件中需要完成页面的布局,拖拽上传等逻辑;

这样封装的意义是为了使得代码更便于维护。

upload.vue 点击上传组件


<template>
    <!--upload.vue 点击上传组件 -->
    <div class="file-selector">
        <z-btn class="selector-btn" color="primary" @click="handleUpClick">
            选择文件
        </z-btn>
        <input
            ref="input"
            class="file-selector-input"
            type="file"
            :multiple="multiple"
            :accept="accept"
            @change="handleFiles"
        />
    </div>
</template>
<script>
    import {debounce} from 'lodash/function';
    export default {
        data() {
            return {
                accept: '.jpg,.jpeg,.png,.gif',
                multiple: false,
                list: [], // 已选择的文件对象
                uploadFinished: true, // 上传状态
                startIndex: 0, // 开始上传的下标,用于追加文件
                maxSize: 10 * 1024 * 1024, //10M(size单位为byte)
                // source: this.$axiOS.CancelToken.source(), // axios 取消请求
            };
        },
        methods: {
            // 重置
            reset() {
                this.list = [];
                this.source.cancel();
                this.startIndex = 0;
                this.uploadFinished = true;
                this.$refs.input && (this.$refs.input.value = null);
            },
            // 调用上传功能
            handleUpClick: debounce(function () {
                // 可在此维护一个上传状态,上传过程中禁用上传按钮
                // if (!this.uploadFinished) this.$message.info('即将覆盖之前的文件~');
                this.$refs.input.click();
            }, 300),
            handleFiles(e) {
                const files = e?.target?.files;
                this.readFiles(files);
            },
            // 上传之前将文件处理为对象
            readFiles(files) {
                if (!files || files.length <= 0) {
                    return;
                }
                for (const file of files) {
                    const url = window.URL.createObjectURL(file);
                    const obj = {
                        title: file.name.replace(/(.*\/)*([^.]+).*/ig, '$2'), // 去掉文件后缀
                        url,
                        file,
                        fileType: file.type,
                        status: 0, // 状态 -> 0 等待中,1 完成, 2 正在上传,3 上传失败
                        percent: 0, // 上传进度
                    };
                    // 提前在 data 中定义 list,用来保存需要上传的文件
                    this.list.unshift(obj);
                    this.$emit('fileList', this.list);
                }
                // 在 data 中定义 startIndex 初始值为 0,上传完成后更新,用于追加上传文件
                // this.startUpload(this.startIndex);
            },

        }
    };
</script>
<style lang="scss">
.file-selector {
    .selector-btn {
        &:hover {
            background-color: rgba($color: #2976e6, $alpha: 0.8);
            transition: background 180ms;
        }
    }

    &-input {
        display: none;
    }
}
</style>

uploadFormDialog.vue 上传对话框


<template>
    <!-- 上传dialog -->
    <form-dialog
        v-model="$attrs.value"
        :title="title"
        persistent
        :loading="loading"
        maxWidth="600px"
        min-height='400px'
        @cancel="handleCancle"
        @confirm="handleSubmit"
    >
        <div
            class="d-flex flex-row justify-space-between">
            <z-form style='width: 260px; height: 100%;'>
                <form-item label="图片名称"  required>
                    <z-text-field
                        v-model="formData.name"
                        outlined
                        :rules="rules"
                        :disabled='disabled'
                        placeholder="请输入图片名称"
                    >
                    </z-text-field>
                </form-item>
                <form-item label="描述" required>
                    <z-textarea
                        v-model="formData.description"
                        outlined
                        :disabled='disabled'
                        placeholder="请输入描述"
                        style="resize: none;"
                    >
                    </z-textarea>
                </form-item>
            </z-form>
            <div ref="pickerArea" class="rightBox">
                <div  class="uploadInputs d-flex flex-column justify-center align-center" :class="[ dragging ? 'dragging' : '']">
                    <div ref="uploadBg"  class="uploadBg my-2"></div>
                    <upload
                        ref="uploadBtn"
                        @fileList='fileList'
                    ></upload>
                    <div class="tip  mt-2">点击上传按钮,或拖拽文件到框内上传</div>
                    <div class="tinyTip ">请选择不大于 10M 的文件</div>
                </div>
            </div>
        </div>

    </form-dialog>

</template>
<script >
    import {debounce} from 'lodash/function';
    import upload from './upload';
    import {uploadImage} from '@/wv-main-admin/apis/image';

    export default {
        components: {
            upload
        },
        props: ['dialogData'],
        data() {
            return {
                dialogFlag: '',
                title: '新增/编辑图片',
                loading: false,
                formData: {
                    name: '',
                    description: ''
                },
                disabled: false,
                rules: [v => !!v || '必填'],
                data: {},
                dragging: true, //是否拖拽
                bindDrop: false,
                fileInfo: {},
            };
        },

        mounted() {

        },
        beforeDestroy() {
            // 组件销毁前解绑拖拽事件
            try {
                const dropbox = this.$refs.pickerArea;
                dropbox.removeEventListener('drop', this.handleDrop);
                dropbox.removeEventListener('dragleave', this.handleDragLeave);
                dropbox.removeEventListener('draGover', this.handleDragOver);
                this.bindDrop = false;
            } catch (e) { console.log(e, '======我是组件销毁前解绑拖拽事件的异常'); }
        },
        methods: {
            //取消
            handleCancle() {
                // 关闭当前弹框
                this.$emit('input', false);
                // 强制组件刷新
                this.$forceUpdate();
            },
            handleSubmit: debounce(function () {
                // 上传单个文件
                const flag = this.checkMustsItem();
                if (flag) {
                    this.startUpload();
                    // 上传完成,强制组件刷新
                    this.$forceUpdate();
                }
            }, 300),

            //监听子组件的值
            fileList(data) {
                this.fileInfo = data[0];
                this.formData.name = this.fileInfo.title;
                const uploadBg = this.$refs.uploadBg;
                //改变背景图片
                uploadBg.style.backgroundImage = `url(${this.fileInfo.url})`;
            },
            bindEvents() {
                const dropbox = this.$refs.pickerArea;
                // 防止重复绑定事件,需要在 data 中初始化 bindDrop 为 false
                if (!dropbox || this.bindDrop) { return; }
                // 绑定拖拽事件,在组件销毁时解绑
                dropbox.addEventListener('drop', this.handleDrop, false);
                dropbox.addEventListener('dragleave', this.handleDragLeave);
                dropbox.addEventListener('dragover', this.handleDragOver);
                this.bindDrop = true;
            },
            // 拖拽到上传区域
            handleDragOver(e) {
                e.stopPropagation();
                e.preventDefault();
                this.dragging = true;
            },
            // 离开上传区域
            handleDragLeave(e) {
                e.stopPropagation();
                e.preventDefault();
                this.dragging = false;
            },
            // 拖拽结束
            handleDrop(e) {
                e.stopPropagation();
                e.preventDefault();
                this.dragging = false;
                const files = e.dataTransfer.files;
                // 调用 <upload/> 组件的上传功能
                this.$refs.uploadBtn && this.$refs.uploadBtn.readFiles(files);
            },
            // 上传前需要校验文件
            checkFile(index) {
                const file = this.list[index];
                // 如果文件不存在,即全部文件上传完成
                if (!file) {
                    // 上传完成,向父组件抛出 success 事件
                    this.uploadFinished = true;
                    this.$emit('success', this.list);
                    // 清空上传控件中的值,保证 change 事件能正常触发
                    this.$refs.input.value = null; this.startIndex = index > 1 ? index - 1 : 0;
                    return false;
                }

                // 校验是否已上传
                if (`${file.status}` === '1') {
                    this.startUpload(++index);
                    return false;
                }

                // 校验文件大小
                if (this.maxSize && file.file && file.file.size >= this.maxSize) {
                    this.startUpload(++index);
                    return false;
                }

                return true;
            },
            checkMustsItem() {
                if (!this.fileInfo.file) {
                    this.$message.warning('请上传文件!');
                    return false;
                } if (!this.formData.name) {
                    this.$message.warning('请输入文件名称!');
                    return false;
                } if (!this.formData.description) {
                    this.$message.warning('请输入文件描述!');
                    return false;
                }
                return true;
            },
            // 上传单个文件
            startUpload() {
                this.loading = true;
                const params = {
                    type: 'image'
                };
                this.$set(params, 'file', this.fileInfo.file);
                this.$set(params, 'name', this.formData.name);
                this.$set(params, 'description', this.formData.description);
                uploadImage(params)
                    .then(res => {
                        this.loading = false;
                        if (res.code === 0) {
                            this.$message.success('上传成功~');
                            this.$emit('refreshList', false);
                            this.$emit('input', false);
                        }
                    })
                    .catch(() => {
                        this.loading = false;
                    });
                // this.$axios({
                //     url: this.url, // 上传接口,由 props 传入
                //     method: 'post',
                //     data,
                //     withCredentials: true,
                //     cancelToken: this.source.token, // 用于取消接口请求
                //     // 进度条
                //     onUploadProgress: e => {
                //         if (fileObj.status === 1) { return; } // 已上传
                //         // 限定最大值为 99%
                //         const p = parseInt((e.loaded / e.total) * 99);
                //         if (e.total) {
                //             fileObj.status = 2; // 正在上传
                //             fileObj.percent = p; // 更新上传进度
                //         } else {
                //             fileObj.status = 3; // 上传失败
                //         }
                //     },
                // })
                //     .then(response => {
                //         if (`${response.code}` === '200') {
                //             fileObj.status = 1;
                //             fileObj.percent = 100;
                //         } else {
                //             fileObj.status = 3;
                //         }
                //     })
                //     .catch(e => {
                //         console.log(e, '====error');
                //         fileObj.status = 3;
                //     })
                //     .finally(e => {
                //         console.log(e, '====error');

                //         this.startUpload(++index);
                //     });
                // 上传完成
            },
        },
    };
</script>

<style lang='scss' scoped>
    .rightBox {
        width: 260px;
        height: 250px;
        border: 1px solid #ccc;
        margin-top: 18px;

        .uploadBg {
            width: 150px;
            height: 125px;
            background: url("../../../../assets/upload.png") no-repeat center center;
            background-size: contain;
        }
        .tip {
            font-size: 13px;
            color: rgba(0, 0, 0, 0.87);
        }
        .tinyTip {
            font-size: 12px;
            color: #8e8f9e;
        }
    }

</style>

注:以上代码用到了我们自己封装的组件库和自己封装的一些方法,请根据具体场景进行相关的修改。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: vue实现拖拽或点击上传图片

本文链接: https://www.lsjlt.com/news/135119.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • vue实现拖拽或点击上传图片
    本文实例为大家分享了vue实现拖拽或点击上传图片的具体代码,供大家参考,具体内容如下 一、预览图 二、实现 点击上传思路:将input的type设置为“file”类型即可上传文件...
    99+
    2022-11-12
  • html5实现拖拽上传图片功能
    这篇文章主要讲解了“html5实现拖拽上传图片功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“html5实现拖拽上传图片功能”吧! ...
    99+
    2022-10-19
  • html5怎么实现多图片预览上传及点击可拖拽控件
    小编给大家分享一下html5怎么实现多图片预览上传及点击可拖拽控件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在做图片上传时发现一个蛮好用的控件,支持多张图片同...
    99+
    2023-06-09
  • vue实现图片拖拽功能
    本文实例为大家分享了vue实现图片拖拽功能的具体代码,供大家参考,具体内容如下 1、主要涉及到的元素知识,示意图: 2、js代码部分: directives: { dr...
    99+
    2022-11-12
  • 使用element+vuedraggable实现图片上传拖拽排序
    本文实例为大家分享了用element+vuedraggable实现图片上传拖拽排序的具体代码,供大家参考,具体内容如下 <template>     <div cl...
    99+
    2022-11-13
  • 微信小程序图片上传组件实现图片拖拽排序
    目录引言首先来看效果组件设计使用方式总结引言 图片上传组件是一个组件库目前来看必不可少的功能了。笔者近日给自己开源的toy工具库也添加了这一功能。相比原生和大部分组件库来说,它不仅支...
    99+
    2022-11-13
  • vue怎么实现图片拖拽功能
    本篇内容介绍了“vue怎么实现图片拖拽功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!主要涉及到的元素知识,示意图:js代码部分:dire...
    99+
    2023-06-25
  • vant uploader实现上传图片拖拽功能(设为封面)
    效果图如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset...
    99+
    2022-11-12
  • 怎么使用element+vuedraggable实现图片上传拖拽排序
    这篇文章主要介绍了怎么使用element+vuedraggable实现图片上传拖拽排序的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用element+vuedraggable实现图片上传拖拽排序文章都会有...
    99+
    2023-06-29
  • HTML5+CSS3如何实现无插件拖拽上传图片功能
    这篇文章主要为大家展示了“HTML5+CSS3如何实现无插件拖拽上传图片功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML5+CSS3如何实现无插件拖拽...
    99+
    2022-10-19
  • 实现vue图片缩放方式-拖拽组件
    目录实现效果如下父组件如下子组件imgbox.vue如下实现效果如下 这几天做了个没做过的组件,以此记录下,需要的效果是在一个dom内,缩放拖拽图片。 封装的子组件imgbox.V...
    99+
    2022-11-13
  • 怎么使用HTML5与CSS3实现无插件拖拽上传图片功能
    这篇文章主要介绍“怎么使用HTML5与CSS3实现无插件拖拽上传图片功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用HTML5与CSS3实现无插件拖拽上传图片功能”文章能帮助大家解决问题。...
    99+
    2023-07-04
  • Vue实现图片预览效果实例(放大、缩小、拖拽)
    前言 这张图是显示的图片放大的一个预览情况,这里是参考预览操作实现的一个背景为黑色的部分,上层的图片可实现滚轮放大或者点击上部的放大镜图标进行放大,代码是基于Ant Design V...
    99+
    2022-11-12
  • ImgUploadJS中如何使用HTML5 File API 实现截图粘贴上传、拖拽上传
    这篇文章将为大家详细讲解有关ImgUploadJS中如何使用HTML5 File API 实现截图粘贴上传、拖拽上传 ,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一 . 背景及效果 当前互联网上传文件最...
    99+
    2023-06-09
  • jQuery如何实现点击头像上传并预览图片
    这篇文章主要为大家展示了“jQuery如何实现点击头像上传并预览图片”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“jQuery如何实现点击头像上传并预览图片”这...
    99+
    2022-10-19
  • Android 在viewPager中双指缩放图片双击缩放图片单指拖拽图片的实现思路
    我们就把这个问题叫做图片查看器吧,它的主要功能有:双击缩放图片。 双指缩放图片。单指拖拽图片。为此这个图片查看器需要考虑以下的技术点:一、双击缩放图片:如果图片高度比屏幕的高度小得多,那么就将图片放大到高度与屏幕高度相等,否则就放大一个特定...
    99+
    2023-05-31
    android viewpager 图片缩放
  • vue draggable组件实现拖拽及点击无效问题的解决
    目录一、效果图二、拖拽及点击无效解决方法三、vuedraggable的使用在实现一个移动端项目的时候,根据产品需求,要实现一个既能增加删除又可以拖拽调换位置的效果,然后我使用了dra...
    99+
    2022-11-13
  • 利用vue组件实现图片的拖拽和缩放功能
    目录前言如图所示:方法如下:总结前言 vue实现一个组件其实很简单但是要写出一个好的可复用的组件那就需要多学习和钻研一下,一个好的组件必须有其必不可少的有优点:一是能提高应用开发效率...
    99+
    2022-11-13
  • Node.js: express + MySQL + Vue实现图片上传
            前段时间用Node.js: express + MySQL + Vue + element组件做了一个小项目,记录一下图片上传的实现。         将图片存入数据库有两种方法:                 1,将图片...
    99+
    2023-09-01
    vue.js node.js express
  • Web如何实现点击图片弹出上传文件窗口
    这篇文章主要介绍Web如何实现点击图片弹出上传文件窗口,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!代码如下:<style> .fileInputContainer{ height:2...
    99+
    2023-06-08
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作