一、话不多说先看实际效果
二、直接上源码
<!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 的组件库中,直接拿来使用的话,只有当前显示效果,一旦刷新页面或者保存之后,就会丢失,预览和删除功能。当保存后,保存到后端接口,再次查看,图片是能渲染出来,但是由于保存页面刷新,随之整个上传过程失败,而查看所拿到的图片只是一张静态图片,要想再次预览和查看,需要重新选中上传。
总结:在当前页面,上传之后可以预览删除,但是跳转或者保存刷新之后,预览和删除事件丢失,需要再次走上传流程,从用户角度看,完全没有了体验感,