vue2 + element 实现手动上传base64编码图片、预览图片、下载图片、删除图片。
浏览器选择本地图片后,前端程序将图片转成base64编码。点击“保存”按钮,提交图片的base64编码到服务端。
文件 hetong.vue。注意,请根据实际项目中的数据使用变量info。
<template>
<div id="create" class="create" style="overflow-y: auto; position: relative; height: 100%;">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="130px">
<el-form-item label="合同">
<el-upload multiple
list-type="picture-card"
action=""
:auto-upload="false"
:on-change="handleChange"
:file-list="fileList"
:on-exceed="handleExceed"
accept=".jpg,.png,.jpeg,.gif"
:before-upload="onBeforeUpload">
<i slot="default" class="el-icon-plus">i>
<div slot="file" slot-scope="{file}">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in">i>
span>
<span class="el-upload-list__item-delete" @click="handleDownload(file)">
<i class="el-icon-download">i>
span>
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete">i>
span>
span>
div>
el-upload>
<div style="font-size: 12px;color: #8c939d">
<i class="el-icon-warning-outline">i>
<span>只能上传jpg、png、jpeg、gif格式的图片,且不超过5Mspan>
div>
el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">保存el-button>
el-form-item>
el-form>
<el-dialog :visible.sync="dialogVisible" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="">
el-dialog>
div>
template>
<script>
module.exports = {
name: "renyuan_hetong",
props: {
info:Object //注意,请根据实际项目中的数据使用变量info
},
data: function () {
return {
dialogImageUrl: '',
dialogVisible: false,
fileList: [],
fileListBase: {},//存放图片base64编码
ruleForm: {
contract: []
},
rules: {},
}
},
created: function () {
console.log('renyuan_hetong created');
},
methods: {
// 上传前检验
onBeforeUpload: function (file) {
const isJPG =
file.type === 'image/jpg' || file.type === 'image/png' || file.type === 'image/jpeg' || file.type === 'image/gif';
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isJPG) {
this.$message.error('上传图片只能是 JPG, PNG, JPEG, GIF 格式!');
}
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
},
// 校验数量
handleExceed(files, fileList) {
this.$message.warning('请先删除图片在重新上传');
},
// 删除图片
handleRemove(file) {
let findIndex = -1;
let findK = -1;
for (let index in this.fileList) {
let item = this.fileList[index];
if (item.uid == file.uid) {
findIndex = index;
findK = file.uid;
break;
}
}
if (findIndex > -1) {
this.fileList.splice(findIndex, 1);
}
if (findK > -1) {
delete this.fileListBase[findK];
}
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleDownload(file) {
let name = this.info.staff.name + '_合同_' + this.info.company.name;
let imgsrc = file.url;
let image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.src = imgsrc;
image.onload = function() {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
let a = document.createElement("a"); // 生成一个a元素
let event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "photo"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
}
},
// 上传时触发
handleChange(file, fileList) {
let _this = this;
_this.fileToBase64(file.raw, function (res) {
let k = file.uid;
_this.fileListBase[k] = res.target.result;
});
this.fileList = fileList;
},
fileToBase64(file, callback) {
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = function (result) {
callback(result)
}
},
submitForm(formName) {
let _this = this, params = this.$data[formName];
params.staff_id = this.info ? this.info.staff_id : null;
params.id = this.info ? this.info.id : null;
params.contract = [];
for (let file of this.fileList) {
if (!file.raw) {
params.contract.push(file.url);
} else {
let k = file.uid;
params.contract.push(_this.fileListBase[k]);
}
}
if (!params.contract) {
_this.$message.error('合同没有变化');
return false;
}
if (!this.info) {
_this.$message.error('没有记录,不能上传合同');
return false;
}
this.$refs[formName].validate((valid) => {
if (valid) {
httpPost('m=zhuchang&c=upContract', params).then(function (response) {
let res = response.data;
if (res.error == 0) {
_this.$message.success(res.msg);
_this.fileList = [];
for (let item of res.data) {
_this.fileList.push({name: 'contract', url: item});
}
_this.$emit("change-hetong");
} else {
_this.$message.error(res.msg);
}
});
} else {
return false;
}
});
}
},
watch: {
info: {
handler: function (val, oldVal) {
console.log('renyuan_hetong watch info', val);
//do ...
if (val.id && val.staff_id) {
this.fileListBase = {};
//展示已存在的图片
this.fileList = [];
for(let item of val.contract_n){
this.fileList.push({name: 'contract', url: item});
}
}
},
deep: true,
immediate: true
}
}
}
script>
<style scoped>
.el-upload-list--picture-card .el-upload-list__item-actions span + span{
margin-left: 10px;
}
style>