element ui 上传图片之后跳转、刷新、保存,预览和删除丢失问题

简介: 这问题困惑了我好久,在官方的element ui 的组件库中,直接拿来使用的话,只有当前显示效果,一旦刷新页面或者保存之后,就会丢失,预览和删除功能。当保存后,保存到后端接口,再次查看,图片是能渲染出来,但是由于保存页面刷新,随之整个上传过程失败,而查看所拿到的图片只是一张静态图片,要想再次预览和查看,需要重新选中上传

一、话不多说先看实际效果

image.png

二、直接上源码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
    <style>
        /* 下边距15px */
        .marginB15 {
   
   
            margin-bottom: 15px;
        }

        /*证照资料名称 */
        .license_uploader-2 {
   
   
            font-size: 13px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            flex-direction: column;
            width: 100%;
            height: 100%;
            line-height: 30px;
        }

        /* 证照资料上传图片 */
        .license_uploader {
   
   
            position: relative;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }

        /* 证照资料显示图片*/
        .license_uploader_img {
   
   
            pointer-events: none;
        }

        /* 证照资料预览图片位置 */
        .license_uploader_mask {
   
   
            position: absolute;
            display: flex;
            align-items: center;
            justify-content: center;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.7);
            opacity: 0;
            transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
        }

        /*证照资料预览阴影 */
        .license_uploader_mask:hover {
   
   
            opacity: 1;
        }

        /* 证照资料icon图样式 */
        .license_uploader_mask i {
   
   
            margin: 0 10px;
            color: #fff;
            font-size: 18px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div style="padding: 20px">
            <el-row :gutter="20">
                <el-col v-for="(item, index) in uploaderArray" :key="index" :span="6" :xs="12" :sm="8" :md="6" :lg="4">
                    <div class="license">
                        <div class="marginB15">
                            <el-upload class="avatar-uploader" action="https:/upload_image"
                                :on-success="handleAvatarSuccess.bind(this, item)"
                                :before-upload="beforeAvatarUpload.bind(this, item)" :show-file-list="false"
                                :disabled="uploaderDisabled" list-type="picture-card">
                                <div v-if="item.imgUrl" class="license_uploader">
                                    <el-image class="license_uploader_img" style="width: 148px; height: 148px"
                                        :src="item.imgUrl"></el-image>
                                    <div class="license_uploader_mask">
                                        <span @click.stop="handlePictureCardPreview(item)">
                                            <i class="el-icon-zoom-in"></i>
                                        </span>
                                        <span @click.stop="handleRemove(item,index)">
                                            <i class="el-icon-delete"></i>
                                        </span>
                                    </div>
                                </div>
                                <div v-else class="license_uploader-2">
                                    <i class="el-icon-plus"></i>
                                    <span>{
   
   {
   
    item.name }}</span>
                                </div>
                            </el-upload>
                        </div>

                    </div>
                </el-col>
                <el-dialog :visible.sync="dialogVisible">
                    <img width="100%" :src="dialogImageUrl" alt="" />
                </el-dialog>
            </el-row>
            <div style="margin-top: 20px">
                <el-button @click="stashAll">暂存</el-button>
                <el-button type="primary" @click="uploadAll">下一步</el-button>
            </div>
        </div>
    </div>
    <!-- <script src="https://unpkg.com/vue/dist/vue.js"></script> -->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.2/vue.js"></script>
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script>
        new Vue({
   
   
            el: "#app",
            data() {
   
   
                return {
   
   
                    dialogVisible: false, // 预览图片对话框  true:显示  flase:隐藏
                    dialogImageUrl: "",
                    uploaderArray: [
                        // 证件上传数组
                        {
   
   
                            name: "test", // 证件名

                        },
                        // {
   
   
                        //     name: "营业执照副本", // 证件名
                        //     imgUrl: "", // 证件上传图片地址
                        // },
                        // {
   
   
                        //     name: "国税税务登记证副本", // 证件名
                        //     imgUrl: "", // 证件上传图片地址
                        // },

                    ],
                    uploaderDisabled: false, // 证件上传 禁用状态
                };
            },

            methods: {
   
   
                fetchLastRecord() {
   
   
                    // todo 接口请求,根据接口回填图片url,即可展示预览等效果
                    // this.uploaderArray = []
                },
                // 删除图片事件
                handleRemove(cell, index) {
   
   
                    console.log(cell);
                    cell.imgUrl = "";
                    this.$set(cell, "temp", false);
                },
                // 预览图片事件
                handlePictureCardPreview(cell) {
   
   
                    this.dialogImageUrl = cell.imgUrl;
                    this.dialogVisible = true; // 显示对话框
                },

                // 图片上传成功后事件
                handleAvatarSuccess(cell, res, file) {
   
   
                    cell.imgUrl = res.data.url;
                },

                // 图片上传前事件
                beforeAvatarUpload(cell, file) {
   
   
                    const isJPG = file.type === "image/jpeg" || "image/png"; // jpg格式
                    const isLt5M = file.size / 1024 / 1024 < 5; // 图片大小不能大于2M

                    if (!isJPG) {
   
   
                        this.$message.error(
                            "上传图片只能是 JPG或PNG 格式!"
                        );
                        return false;
                    }
                    if (!isLt5M) {
   
   
                        this.$message.error(
                            "上传图片大小不能超过 5MB!"
                        );
                        return false;
                    }

                    // 设置预览文件url
                    const url = URL.createObjectURL(file);
                    this.$set(cell, "temp", true);
                    cell.imgUrl = url;

                    return true;
                }, fetchLastRecord() {
   
   
                    // todo 接口请求,根据接口回填图片url,即可展示预览等效果
                    // this.uploaderArray = []
                },
                // 删除图片事件
                handleRemove(cell, index) {
   
   
                    console.log(cell);
                    cell.imgUrl = "";
                    this.$set(cell, "temp", false);
                },
                // 预览图片事件
                handlePictureCardPreview(cell) {
   
   
                    this.dialogImageUrl = cell.imgUrl;
                    this.dialogVisible = true; // 显示对话框
                },

                // 图片上传成功后事件
                handleAvatarSuccess(cell, res, file) {
   
   
                    cell.imgUrl = res.data.url;
                },

                // 图片上传前事件
                beforeAvatarUpload(cell, file) {
   
   
                    const isJPG = file.type === "image/jpeg" || "image/png"; // jpg格式
                    const isLt5M = file.size / 1024 / 1024 < 5; // 图片大小不能大于2M

                    if (!isJPG) {
   
   
                        this.$message.error(
                            "上传图片只能是 JPG或PNG 格式!"
                        );
                        return false;
                    }
                    if (!isLt5M) {
   
   
                        this.$message.error(
                            "上传图片大小不能超过 5MB!"
                        );
                        return false;
                    }

                    // 设置预览文件url
                    const url = URL.createObjectURL(file);
                    this.$set(cell, "temp", true);
                    cell.imgUrl = url;

                    return true;
                },
            },
        });
    </script>
</body>

</html>

这问题困惑了我好久,在官方的element ui 的组件库中,直接拿来使用的话,只有当前显示效果,一旦刷新页面或者保存之后,就会丢失,预览和删除功能。当保存后,保存到后端接口,再次查看,图片是能渲染出来,但是由于保存页面刷新,随之整个上传过程失败,而查看所拿到的图片只是一张静态图片,要想再次预览和查看,需要重新选中上传。
总结:在当前页面,上传之后可以预览删除,但是跳转或者保存刷新之后,预览和删除事件丢失,需要再次走上传流程,从用户角度看,完全没有了体验感,

目录
相关文章
|
9月前
|
API UED 容器
深入探索 Element UI:自定义滚动条与弹出层管理的技巧
在这篇博客中,我们将深入探讨 Element UI 中的自定义滚动条及弹出层管理技巧。文章详细介绍了 el-scrollbar 组件的使用和参数设置,以及 PopupManager 如何有效管理弹出层的 z-index。我们还将探讨如何实现灵活的全屏组件,利用 vue-popper 创建自定义弹出层,最后介绍 ClickOutside 指令的用法。这些高级技巧将帮助你提升 Element UI 应用程序的用户体验与交互灵活性。
797 1
深入探索 Element UI:自定义滚动条与弹出层管理的技巧
|
9月前
|
JavaScript 索引
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
Vue开发中Element UI/Plus使用指南:常见问题(如Missing required prop: “value“)及中文全局组件配置解决方案
688 0
|
11月前
|
JavaScript 前端开发 开发者
决战前端之巅!Element UI与Vuetify谁才是Vue.js组件界的霸主?一场关于颜值与实力的较量!
【8月更文挑战第30天】本文对比了两款热门的Vue.js组件库——Element UI与Vuetify。Element UI由饿了么团队打造,提供多种高质量UI组件,设计简洁大方。Vuetify基于Material Design规范,支持Vue.js 2.0及3.0版本,具备前瞻性。两者均涵盖表单、导航、数据展示等组件,Element UI配置选项丰富,而Vuetify则提供了更深层的样式定制功能。开发者可根据项目需求及个人偏好选择合适的组件库。
793 0
|
11月前
|
开发者 C# Android开发
明白吗?Xamarin与Native的终极对决:究竟哪种开发方式更适合您的项目需求,让我们一探究竟!
【8月更文挑战第31天】随着移动应用开发的普及,开发者面临多种技术选择。本文对比了跨平台解决方案Xamarin与原生开发方式的优势与劣势。Xamarin使用C#进行跨平台开发,代码复用率高,可大幅降低开发成本;但因基于抽象层,可能影响性能。原生开发则充分利用平台特性,提供最佳用户体验,但需维护多套代码库,增加工作量。开发者应根据项目需求、团队技能和预算综合考量,选择最适合的开发方式。
217 0
|
11月前
|
JavaScript 开发者 UED
Vue.js组件库大对决:Element UI与Vuetify,开发者的罗密欧与朱丽叶!
【8月更文挑战第30天】Element UI和Vuetify是Vue.js开发中的热门组件库,前者简洁高效,后者遵循Material Design,国际化程度高。两者均提供丰富的组件支持,但Vuetify组件更多样,设计更灵活;Element UI在性能和中文支持上更优。文档方面,Element UI更直观易懂,而Vuetify配置灵活但学习成本稍高。选择时需综合考虑项目需求、团队背景及设计风格,以达到最佳开发效果。
602 0
|
2月前
|
开发框架 前端开发 JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发一
本文介绍了方舟开发框架(ArkUI)及其两种开发范式:基于ArkTS的声明式开发范式和类Web开发范式。ArkUI是用于构建HarmonyOS应用界面的UI框架,提供极简UI语法和基础设施。声明式开发范式使用ArkTS语言,以组件、动画和状态管理为核心,适合复杂团队协作;类Web开发范式采用HML、CSS、JavaScript三段式开发,适用于简单界面应用,贴近Web开发者习惯。文中还概述了两者的架构和基础能力,帮助开发者选择合适的范式进行高效开发。
84 15
|
2月前
|
编解码 前端开发 Java
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发三
本文介绍了基于声明式UI范式的图形绘制与动画效果实现方法,涵盖绘制图形、添加动画效果及常见组件说明三部分内容。在绘制图形部分,详细讲解了如何通过Circle组件为食物成分表添加圆形标签,以及使用Path组件结合SVG命令绘制自定义图形(如应用Logo)。动画效果部分则展示了如何利用animateTo实现闪屏动画,包括渐出、放大效果,并设置页面跳转;同时介绍了页面间共享元素转场动画的实现方式。最后,文章列举了声明式开发范式中的各类组件及其功能,帮助开发者快速上手构建复杂交互页面。
81 11
|
1月前
|
JavaScript 前端开发 UED
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
122 56
|
1月前
|
编解码 UED 开发者
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发之常见布局
本文主要介绍了自适应布局与响应式布局的相关内容。自适应布局部分涵盖线性布局、层叠布局、弹性布局和网格布局,详细说明了各布局的特性及使用方法,例如线性布局中的排列、拉伸与缩放,弹性布局的方向、换行与对齐方式等。响应式布局则重点讲解了栅格系统和媒体查询,阐述如何通过栅格组件和媒体查询条件实现不同设备上的适配效果。这些技术帮助开发者灵活应对多尺寸屏幕的设计需求,提升用户体验。
138 55
|
2月前
|
存储 开发框架 API
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发二
本文详细介绍了基于声明式UI开发的健康饮食应用的设计与实现过程。内容涵盖从基础环境搭建到复杂功能实现的全流程,包括创建简单视图、构建布局(如Stack、Flex)、数据模型设计、列表与网格布局构建,以及页面跳转和数据传递等核心功能。 本文通过实际案例深入浅出地解析了声明式UI开发的关键技术和最佳实践,为开发者提供了宝贵的参考。
74 14