返回顶部
首页 > 资讯 > 精选 >如何利用Vue3和element-plus实现图片上传组件
  • 845
分享到

如何利用Vue3和element-plus实现图片上传组件

2023-06-29 12:06:27 845人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关如何利用vue3和element-plus实现图片上传组件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言element-plus 提供了 uploader 组件,但是不好定

这篇文章将为大家详细讲解有关如何利用vue3和element-plus实现图片上传组件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

前言

element-plus 提供了 uploader 组件,但是不好定制化,所以自己又造了个轮子,实现了一个图片上传的组件,它的预期行为是:

还没上传图片时,显示上传卡片

上传图片时显示进度条,隐藏上传卡片

上传成功时显示图片缩略图,上传失败则显示失败提示

支持上传图片的预览和删除

具体如下图所示:

如何利用Vue3和element-plus实现图片上传组件

具体代码

图片上传

这里使用的图床是牛图网,无需注册,貌似也没有图片大小的限制,但是请不要上传违规图像。

<code>import axiOS from "axios"import { ElMessage } from 'element-plus'const service = axios.create({    baseURL: "/image"})service.interceptors.response.use(response => {    const code = response.data.code || 200    if (code === 200) {        return response.data.data    }    let msg = response.data.code + " " + response.data.msg    ElMessage.error(msg)    return Promise.reject('上传图片失败:' + msg)})function uploadImage(file, progress) {    let fORMData = new FormData();    formData.append("file", file)    return service({        url: "/upload",        method: "post",        data: formData,        onUploadProgress(event) {            let v = Math.round(event.loaded / event.total * 100)            progress.value = v == 100 ? 80 : v        },    })}export { uploadImage }

这里使用 onUploadProgress 来监视上传进度,但是实际上直接使用计算出来的进度往往会和实际的存在很大的偏差,也就是说:即使你还在上传,axios 也会告诉你已经上传完了,所以这里把 100 的进度换成了 80,真正的 100 进度应该在服务器返回 url 时设置。

受到同源策略的限制,我们需要在 Vue.config.js 中配置一下代理服务器

<code>module.exports = {    devServer: {        proxy: {            "/image": {                target: "https://niupic.com/api",                pathRewrite: { "^/image": "" },            },        }    }}

上传组件

图片预览功能用的是 vue-easy-light-box,如果没有安装的话可以 npm install --save vue-easy-lightbox@next 安装一下。下面是具体代码:

<code><template>    <div class="uploader">        <input            type="file"            id="file-input"                        accept="image/*"            @change="onImageAdded"        />        <div            class="card upload-card"            @click="openFileDialog"            v-if="!isThumbnailVisible"        >            <svg                class="icon"                width="28"                height="28"                viewBox="0 0 1024 1024"                xmlns="Http://www.w3.org/2000/svg"            >                <path                    fill="#8c939d"                    d="M480 480V128a32 32 0 0164 0v352h452a32 32 0 110 64H544v352a32 32 0 11-64 0V544H128a32 32 0 010-64h452z"                ></path>            </svg>        </div>        <div class="card thumbnail-card" v-show="isThumbnailVisible">            <img src="" alt="缩略图" id="thumbnail" />            <label class="success-label" v-show="isSuccessLabelVisible"                ><i class="success-icon"                    ><svg                        class="icon"                        width="12"                        height="12"                        viewBox="0 0 1024 1024"                        xmlns="http://www.w3.org/2000/svg"                    >                        <path                            fill="white"                            d="M406.656 706.944L195.84 496.256a32 32 0 10-45.248 45.248l256 256 512-512a32 32 0 00-45.248-45.248L406.592 706.944z"                        ></path></svg                ></i>            </label>            <!-- 图标 -->            <div class="thumbnail-actions">                <span class="thumbnail-preview" @click="handleThumbnailPreview">                    <svg                        class="icon"                        width="20"                        height="20"                        viewBox="0 0 1024 1024"                        xmlns="http://www.w3.org/2000/svg"                    >                        <path                            fill="white"                            d="M795.904 750.72l124.992 124.928a32 32 0 01-45.248 45.248L750.656 795.904a416 416 0 1145.248-45.248zM480 832a352 352 0 100-704 352 352 0 000 704zm-32-384v-96a32 32 0 0164 0v96h96a32 32 0 010 64h-96v96a32 32 0 01-64 0v-96h-96a32 32 0 010-64h96z"                        ></path>                    </svg>                </span>                <span class="thumbnail-delete" @click="handleThumbnailRemove">                    <svg                        class="icon"                        width="20"                        height="20"                        viewBox="0 0 1024 1024"                        xmlns="http://www.w3.org/2000/svg"                    >                        <path                            fill="white"                            d="M160 256H96a32 32 0 010-64h356V95.936a32 32 0 0132-32h356a32 32 0 0132 32V192h356a32 32 0 110 64h-64v672a32 32 0 01-32 32H192a32 32 0 01-32-32V256zm448-64v-64H416v64h292zM224 896h676V256H224v640zm192-128a32 32 0 01-32-32V416a32 32 0 0164 0v320a32 32 0 01-32 32zm192 0a32 32 0 01-32-32V416a32 32 0 0164 0v320a32 32 0 01-32 32z"                        ></path>                    </svg>                </span>            </div>            <!-- 进度条 -->            <el-progress                type="circle"                :percentage="progress"                v-show="isProgressVisible"                :width="110"                id="progress"            />        </div>        <vue-easy-lightbox            moveDisabled            :visible="isLightBoxVisible"            :imgs="localImageUrl"            :index="index"            @hide="handleLightboxHide"        />    </div></template><script>import { ref, computed } from "vue";import { uploadImage } from "../api/image";import { Plus } from "@element-plus/icons-vue";import VueEasyLightbox from "vue-easy-lightbox";import { ElMessage } from 'element-plus/lib/components';export default {    name: "KilaKilaUploader",    emits: ["uploaded", "aboutToUpload", "removed"],    components: { Plus, VueEasyLightbox },    setup(props, context) {        let progress = ref(0);        let isLightBoxVisible = ref(false);        let isProgressVisible = ref(false);        let isSuccessLabelVisible = ref(false);        let imageUrl = ref("");        let localImageUrl = ref("");        let index = ref(0);        let isThumbnailVisible = computed(() => localImageUrl.value.length > 0);        function openFileDialog() {            document.getElementById("file-input").click();        }        function onImageAdded() {            let fileInput = document.getElementById("file-input");            if (fileInput.files.length == 0) {                return;            }            context.emit("aboutToUpload");            let file = fileInput.files[0];            setImageUrl(URL.createObjectURL(file));            upload(file);        }        function setImageUrl(url) {            let thumbnailEl = document.getElementById("thumbnail");            thumbnailEl.src = localImageUrl.value = url;        }        function handleThumbnailRemove(file) {            imageUrl.value = "";            localImageUrl.value = "";            context.emit("removed", file);        }        function handleThumbnailPreview() {            isLightBoxVisible.value = true;        }        function handleLightboxHide() {            isLightBoxVisible.value = false;        }        function upload(file) {            progress.value = 0;            isProgressVisible.value = true;            isSuccessLabelVisible.value = false;            uploadImage(file, progress).then(                (url) => {                    progress.value = 100;                    imageUrl.value = url;                    document.getElementById("thumbnail").src = url;                    context.emit("uploaded", url);                    setTimeout(() => {                        isProgressVisible.value = false;                        isSuccessLabelVisible.value = true;                    }, 200);                },                () => {                    isProgressVisible.value = false;                    localImageUrl.value = "";                    context.emit("uploaded", "");                    ElMessage.error("哎呀,图片上传出错啦~")                }            );        }        return {            progress,            imageUrl,            localImageUrl,            index,            isLightBoxVisible,            isThumbnailVisible,            isProgressVisible,            isSuccessLabelVisible,            handleThumbnailRemove,            handleThumbnailPreview,            handleLightboxHide,            openFileDialog,            onImageAdded,            setImageUrl,        };    },};</script><style lang="less" scoped>.uploader {    display: flex;}.card {    background-color: #fbfdff;    border: 1px dashed #c0ccda;    border-radius: 6px;    width: 148px;    height: 148px;    overflow: hidden;}.upload-card {    display: flex;    justify-content: center;    align-items: center;    transition: all 0.3s;    cursor: pointer;    &:hover {        border-color: #409eff;        color: #409eff;    }}.thumbnail-card {    border: 1px solid #c0ccda;    position: relative;    #thumbnail {        width: 100%;        height: 100%;        object-fit: contain;        display: inline;    }    .success-label {        position: absolute;        right: -15px;        top: -6px;        width: 40px;        height: 24px;        background: #67c23a;        text-align: center;        transform: rotate(45deg);        box-shadow: 0 0 1pc 1px #0003;        .success-icon {            position: absolute;            left: 13px;            top: 1px;            transform: rotate(-45deg);        }    }    #progress {        width: 100%;        height: 100%;        position: absolute;        top: 0;        left: 0;        background: rgba(255, 255, 255, 0.7);        :deep(.el-progress-circle) {            position: absolute;            top: 50%;            left: 50%;            transform: translate(-50%, -50%);        }    }    .thumbnail-actions {        width: 100%;        height: 100%;        background: rgba(0, 0, 0, 0.5);        opacity: 0;        transition: all 0.4s ease;        display: flex;        justify-content: center;        align-items: center;        position: absolute;        top: 0;        left: 0;        border-radius: 6px;        .thumbnail-preview,        .thumbnail-delete {            cursor: pointer;            margin: 0 8px;            display: inline-block;        }        &:hover {            opacity: 1;        }    }}:deep(.vel-img) {    box-shadow: 0 5px 20px 2px rgba(0, 0, 0, 0.35);}</style>

在图片上传之前、上传完成和移除图片的时候都会触发相应的自定义事件,父级组件可以处理这些事件来设置图片 url。

关于“如何利用Vue3和element-plus实现图片上传组件”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: 如何利用Vue3和element-plus实现图片上传组件

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

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

猜你喜欢
  • 如何利用Vue3和element-plus实现图片上传组件
    这篇文章将为大家详细讲解有关如何利用Vue3和element-plus实现图片上传组件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言element-plus 提供了 uploader 组件,但是不好定...
    99+
    2023-06-29
  • 利用Vue3和element-plus实现图片上传组件
    目录前言具体代码图片上传上传组件前言 element-plus 提供了 uploader 组件,但是不好定制化,所以自己又造了个轮子,实现了一个图片上传的组件,它的预期行为是: 1....
    99+
    2024-04-02
  • 利用Vue3+Element-plus实现大文件分片上传组件
    目录一、背景二、技术栈三、核心代码实现四、总结一、背景 实际项目中遇到需要上传几十个G的3d模型文件,传统上传就不适用了。 结合element提供的上传组件自己封装了文件分片上传的组...
    99+
    2023-01-28
    elementui分片上传 vue element ui教程 element ui 上传文件组件
  • Vue3.x+Element Plus如何实现分页器组件
    这篇文章主要介绍“Vue3.x+Element Plus如何实现分页器组件”,在日常操作中,相信很多人在Vue3.x+Element Plus如何实现分页器组件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
    99+
    2023-07-05
  • vue如何实现上传图片组件
    这篇文章给大家分享的是有关vue如何实现上传图片组件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。未上传状态上传状态其他状态(查看/删除)自定义组件文件名称 - 这里叫UploadImg.vue<templ...
    99+
    2023-06-25
  • vue如何使用element实现上传图片和修改图片功能
    本篇内容主要讲解“vue如何使用element实现上传图片和修改图片功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue如何使用element实现上传图片和修改图片功能”吧!一、应用场景1....
    99+
    2023-07-02
  • vue使用element实现上传图片和修改图片功能
    目录前言一、应用场景1.上传图片并进行放大预览2.图片上传代码二、修改已经上传的图片,并展示到图片列表中1.效果展示(先展示原来的图片,再上传新图片,也可删除原来的图片)2.编辑代码...
    99+
    2024-04-02
  • 如何利用HTML5实现图片文件异步上传
    小编给大家分享一下如何利用HTML5实现图片文件异步上传,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 1.文件未选择 2.文...
    99+
    2024-04-02
  • element-ui如何实现上传图片后清空图片显示
    这篇文章主要为大家展示了“element-ui如何实现上传图片后清空图片显示”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“element-ui如何实现上传图片后...
    99+
    2024-04-02
  • Vue3 Element Plus中el-form表单组件如何使用
    这篇文章主要讲解了“Vue3 Element Plus中el-form表单组件如何使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue3 Element&n...
    99+
    2023-07-06
  • vue-cropper组件如何实现图片切割上传
    小编给大家分享一下vue-cropper组件如何实现图片切割上传,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!vue-cropper在vue中的引入1、组件内引入...
    99+
    2023-06-15
  • 如何使用Vue3和ElementPlus前端实现分片上传
    这篇文章主要讲解了“如何使用Vue3和ElementPlus前端实现分片上传”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Vue3和ElementPlus前端实现分片上传”吧!1. ...
    99+
    2023-07-04
  • vue如何实现上传图片文件
    这篇文章给大家分享的是有关vue如何实现上传图片文件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。原始input标签form表单上传<input type="file"&nbs...
    99+
    2023-06-15
  • Vue3 Element-plus和el-menu无限级菜单组件如何封装
    本文小编为大家详细介绍“Vue3 Element-plus和el-menu无限级菜单组件如何封装”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue3 Element-plus和el-menu无限级菜单组件如何封装”文...
    99+
    2023-07-06
  • 如何利用node+koa+axios实现图片上传和回显功能
    今天小编给大家分享一下如何利用node+koa+axios实现图片上传和回显功能的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧...
    99+
    2023-06-30
  • 基于vue3和element-plus的暗黑模式如何实现
    这篇文章主要介绍“基于vue3和element-plus的暗黑模式如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于vue3和element-plus的暗黑模式如何实现”文章能帮助大家解决问...
    99+
    2023-07-06
  • vue-cropper组件实现图片切割上传
    本文实例为大家分享了vue-cropper组件实现图片切割上传的具体代码,供大家参考,具体内容如下 这几日,等来了些空闲,用vue和spring boot实践一次头像上传,因此记下...
    99+
    2024-04-02
  • 使用element+vuedraggable实现图片上传拖拽排序
    本文实例为大家分享了用element+vuedraggable实现图片上传拖拽排序的具体代码,供大家参考,具体内容如下 <template>     <div cl...
    99+
    2024-04-02
  • 怎么使用vue+element-plus实现上传图片、回显问题及数量限制
    这篇文章主要介绍“怎么使用vue+element-plus实现上传图片、回显问题及数量限制”,在日常操作中,相信很多人在怎么使用vue+element-plus实现上传图片、回显问题及数量限制问题上存在疑惑,小编查阅了各式资料,整理出简单好...
    99+
    2023-07-06
  • element-ui如何实现上传一张图片后隐藏上传按钮功能
    这篇文章给大家分享的是有关element-ui如何实现上传一张图片后隐藏上传按钮功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。element-ui上传一张图片后隐藏上传按钮 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作