vue---图像上传/裁剪/预览/删除/查询
案例功能:1、查询图片:从后台读取图片(url),并排列显示。2、新增图片:选择图像->图像裁剪->上传图像(base64)3、删除图片(ps:完整代码见篇末)实现效果:最多可上传3张符合图片格式要求的照片。删除第一张图片后,出现【添加照片】,可继续添加1张照片删除上图的第一张图片后,出现【添加照片】,可继续依次添加2张照片案例思路:...
目录
FileReader.readAsDataURL(file)
一、案例功能
1、查询图片:使用axios从服务器读取图片(url图片路径名),并排列显示。
2、新增图片:选择图像(FileReader)->图像裁剪(Vue-Cropper)->上传图像(base64)
3、删除图片
(ps:完整代码见篇末)
二、实现效果
点击【添加照片】方形区域打开文件夹选择图片,选择完成后弹出裁剪图片的对话框,点击【点击上传】按钮向后台提交图片。
选择图像:最多可上传3张照片,当没有照片上传时,【上传照片】区域仅有一个【添加照片;当第一张图片上传成功,【添加照片】出现在该图片后的第二个位置;当第二张图片上传成功,【添加照片】出现在该图片后的第三个位置;当第三张图片上传成功,【添加照片】不再出现。
图像裁剪:可对图片进行放大、缩小、左旋转、右旋转、下载及预览功能。
图像上传:上传满足图片要求的图片。
图像删除:鼠标移入图片出现删除图标,可点击进行删除操作,鼠标移出图片隐藏删除图标。
三、知识点介绍
File
File
接口提供有关文件的信息,并允许网页中的 JavaScript 访问其内容。通常情况下,File
对象是来自用户在一个 <input>元素上选择文件后返回的FileList 对象,也可以是来自由拖放操作生成的 DataTranfer对象,或者来自HTMLCanvasElement 上的mozGetAsFile
() API。
File对象可以用来获取某个文件的信息,还可以用来读取这个文件的内容。
案例中,File对象来自用户在一个<input>元素上选择文件后返回的FileList对象【let file = this.$refs.photoFile.files[0];】
<img v-show="(this.photoCount<3)" :src="this.uploadImage" @click="uploadPhoto" />
<input type="file" hidden ref="photoFile" @change="fileChange" style="display: none;" />
// 本地上传头像
uploadPhoto() {
this.$refs.photoFile.click();
},
// 修改头像
fileChange(e) {
let file = this.$refs.photoFile.files[0];
if (/.(png|jpg|jpeg|JPG|JPEG)$/.test(file.name)) {
let fr = new FileReader();
fr.readAsDataURL(file);
fr.onload = e => {
// 将图像置于裁剪框中
this.option.img = e.target.result;
this.cropImageFormVisible = true;
this.$refs.photoFile.value = "";
};
} else {
this.$message({
message: "请选择符合格式要求的图片",
type: "warning"
});
this.$refs.photoFile.value = "";
}
},
File
对象是来自用户通过【 <input type="file" hidden ref="photoFile" @change="fileChange" style="display: none;" />】元素上选择文件后返回的 FileList
对象,本案例只能一次上传一张图片,因此files.length=1。可以通过files[index]获取我们选择的file对象。
当为<input>添加属性【 multiple="multiple"】,即【<input type="file" hidden multiple="multiple" ref="photoFile" @change="fileChange" style="display: none;" />】时,可选择N个文件,files.length=N。
FileReader
FileReader:FileReader对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob对象指定要读取的文件或数据。
File
对象是特殊类型的 Blob
,且可以用在任意的 Blob 类型的 context 中。
FileReader.
readAsDataURL(file)
FileReader
.
readAsDataURL(file)开始读取指定的Blob中的内容。一旦完成,result
属性中将包含一个data:
URL格式的Base64字符串以表示所读取文件的内容。
【this.option.img = e.target.result;】 e.target.result为base64形式的字符串,称之为DataURL对象。在Data URL协议中,图片被转换成base64编码的字符串形式,并存储在URL中。
FileReader.
onload
FileReader
.
onload处理load事件,在读取操作开始时触发。
VueCropper
四、案例思路
1、通过设置一个标志(true/false)控制【添加照片】是否显示,当查询到后台传过来的图片个数<3时,标志为true,【添加照片】显示,否则标志为false,【添加照片】隐藏。
2、当鼠标移入图像时,出现删除按钮,鼠标移出图像时,删除按钮消失。通过css样式实现,设置【删除图标】样式为不可见【.delete-img {display: none;}】,当【li:hover】时设置【删除图标】样式可见【display: block】即可。
五、完整代码
<template>
<div class="personal">
<div class="content">
<!-- 1.标题及图像说明 -->
<div class="content-desc">
<div class="title">上传照片</div>
<div class="desc">照片要求为清晰无遮挡的人脸正脸照,格式为jpg/jpeg/png,最多可上传3张照片</div>
</div>
<!-- 2.图像区域 -->
<ul class="content-image">
<li v-for="(item, index) in image" :key="index">
<img :src="item.imageUrl" />
<!-- 删除图标 -->
<div class="delete-img">
<i class="el-icon-delete" @click="deleteImage(index,item.id)"></i>
</div>
</li>
<!-- 控制最多可上传三张图片 -->
<img
class="upload-img"
v-show="(this.photoCount<3)"
:src="this.uploadImage"
@click="uploadPhoto"
/>
</ul>
<input type="file" hidden ref="photoFile" @change="fileChange" style="display: none;" />
</div>
<!-- 上传图像前调整图像的尺寸 -->
<el-dialog title="修改头像" :visible.sync="cropImageFormVisible" class="cropImageForm" width="50%">
<div class="img-crop">
<!-- 1.截图区域 -->
<div class="imgCrop-content">
<div class="cropper-content">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"
@realTime="realTime"
@imgLoad="imgLoad"
></vueCropper>
</div>
<div class="preview-content">
<div class="show-preview">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img" />
</div>
</div>
<p class="desc">预览图片</p>
</div>
</div>
<!-- 2.操作按钮区域 -->
<div class="btn-content">
<input class="btn" type="button" value="+" title="放大" @click="changeScale(1)" />
<input class="btn" type="button" style value="-" title="缩小" @click="changeScale(-1)" />
<input class="btn" type="button" value="↺" title="左旋转" @click="rotateLeft" />
<input class="btn" type="button" value="↻" title="右旋转" @click="rotateRight" />
<input class="btn" type="button" value="↓" title="下载" @click="down('blob')" />
</div>
</div>
<div class="btn-footer">
<el-button @click="cropImageFormVisible= false" size="small">取 消</el-button>
<el-button type="danger" @click="submitPhoto" size="small">点击上传</el-button>
</div>
</el-dialog>
<!-- 删除对话框 -->
<el-dialog title="删除" :visible.sync="deleteImageFormVisible" width="30%" class="deleteRoleForm">
<span>是否删除该照片?</span>
<span slot="footer" class="dialog-footer">
<el-button size="mini" @click="deleteImageFormVisible = false">取 消</el-button>
<el-button size="mini" type="primary" @click="submitDeleteImage">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { VueCropper } from "vue-cropper";
import {
imageAdd,
imageQuery,
imageDelete,
dictListQuery
} from "../../api/http";
export default {
data() {
return {
cropImageFormVisible: false,
deleteImageFormVisible: false,
deleteImgId: null,
deleteIndex: null,
image: [
// {
// imageUrl:
// "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
// id: 1
// },
// {
// imageUrl:
// "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",
// id: 2
// },
// {
// imageUrl:
// "https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg",
// id: 3
// }
],
photoCount: 0,
uploadImage: "",
//剪切图片上传
previews: {},
option: {
img: "",
outputSize: 1, //剪切后的图片质量(0.1-1)
full: false, //输出原图比例截图 props名full
outputType: "png",
canMove: true,
original: false,
canMoveBox: true,
autoCrop: true,
autoCropWidth: 150,
autoCropHeight: 150,
fixedBox: true
},
downImg: "#",
host: "" //存放图像的服务器ip及端口
};
},
components: {
VueCropper
},
created() {
// uploadImage用于存放“添加照片”图片base64,
this.uploadImage =
"data:image/png;base64,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";
this.photoCount = this.image.length;
// *******查询系统参数配置--用于获取图像服务器ip及端口*****/
let param1 = {
token: this.$store.state.token,
tag: "系统参数配置",
currentPage: 1,
pageSize: 10
};
dictListQuery(param1).then(res => {
var hostArray = res.data.result.records.filter(function(fh) {
return fh.name === "faceImage_server_host";
});
this.host = hostArray[0].value;
//******查询人脸图像信息********
this.getImageData();
});
},
methods: {
//******查询人脸图像信息********
getImageData() {
// this.image = [];
let param = {
token: this.$store.state.token,
currentPage: 1,
pageSize: 10
};
imageQuery(param).then(res => {
if (res.data.respCode == "00000") {
var urlArray = res.data.result.records;
this.image = urlArray;
for (var i = 0; i < urlArray.length; i++) {
this.image[i].imageUrl = this.host + urlArray[i].url;
}
this.photoCount = urlArray.length;
} else {
this.$message.error(res.data.respDesc);
}
});
},
// 本地上传头像
uploadPhoto() {
this.$refs.photoFile.click();
},
// 修改头像
fileChange(e) {
console.log("输出files:", this.$refs.photoFile.files);
let file = this.$refs.photoFile.files[0];
if (/.(png|jpg|jpeg|JPG|JPEG)$/.test(file.name)) {
let fr = new FileReader();
fr.readAsDataURL(file);
fr.onload = e => {
// 将图像置于裁剪框中
console.log("输出e:", e);
this.option.img = e.target.result;
this.cropImageFormVisible = true;
this.$refs.photoFile.value = "";
};
} else {
this.$message({
message: "请选择符合格式要求的图片",
type: "warning"
});
this.$refs.photoFile.value = "";
}
},
// 上传图像
submitPhoto() {
this.$refs.cropper.getCropData(data => {
let param = {
token: this.$store.state.token,
image: data
};
imageAdd(param).then(res => {
// console.log("提交新增图片:", res);
if (res.data.respCode == "00000") {
this.$message.success(res.data.respDesc);
this.photoCount++;
this.cropImageFormVisible = false;
this.getImageData();
} else {
this.$message.error(res.data.respDesc);
}
});
});
},
// 删除图片
deleteImage(index, id) {
this.deleteImgId = id;
this.deleteIndex = index;
this.deleteImageFormVisible = true;
},
// 提交删除图片
submitDeleteImage() {
this.deleteImageFormVisible = false;
let param = {
token: this.$store.state.token,
imageId: this.deleteImgId
};
imageDelete(param).then(res => {
// console.log(" 提交删除:", res);
if (res.data.respCode == "00000") {
// this.image.splice(this.deleteIndex, 1);
this.photoCount--;
this.$message.success(res.data.respDesc);
} else {
this.$message.error(res.data.respDesc);
}
this.getImageData();
});
},
//放大/缩小
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//左旋转
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
//右旋转
rotateRight() {
this.$refs.cropper.rotateRight();
},
// 实时预览函数
realTime(data) {
this.previews = data;
},
//下载图片
down(type) {
var aLink = document.createElement("a");
aLink.download = "author-img";
if (type === "blob") {
this.$refs.cropper.getCropBlob(data => {
this.downImg = window.URL.createObjectURL(data);
aLink.href = window.URL.createObjectURL(data);
aLink.click();
});
} else {
this.$refs.cropper.getCropData(data => {
this.downImg = data;
aLink.href = data;
aLink.click();
});
}
},
imgLoad(msg) {}
}
};
</script>
<style lang="less">
.personal {
margin: 10px 0;
padding: 10px;
background: #f0f0f0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow-y: hidden;
border-radius: 3px;
padding-bottom: 20px;
.content {
background-color: #fff;
width: 100%;
height: 100%;
border-radius: 6px;
padding: 10px;
// overflow-y: scroll;
overflow: hidden;
display: flex;
padding: 10px 0;
flex-direction: column;
// 1.标题及图像说明
.content-desc {
margin: 0px 10px;
.title {
font-size: 16px;
border-left: 5px solid #2d8cf0;
padding-left: 10px;
margin-bottom: 16px;
}
.desc {
margin-left: 18px;
}
}
// 2.图像区域
.content-image {
display: flex;
justify-content: rows;
margin: 20px 30px;
li {
width: 180px;
height: 180px;
margin-right: 20px;
position: relative;
.delete-img {
display: none;
}
&:hover {
.delete-img {
display: block;
position: absolute;
width: 180px;
height: 40px;
line-height: 40px;
left: 0px;
top: 140px;
background: rgba(59, 60, 61, 0.5);
// box-sizing: content-box;
z-index: 999;
cursor: pointer;
text-align: right;
i {
margin: 8px 10px 0 0;
display: block;
font-size: 24px;
color: white;
}
}
}
}
img {
width: 180px;
height: 180px;
border-radius: 4px;
}
.upload-img:hover {
border: 1px dashed #92cccc;
}
}
}
// 裁剪图像对话框
.cropImageForm {
.img-crop {
// 1.截图区域
.imgCrop-content {
margin: 0 20px;
display: flex;
display: -webkit-flex;
justify-content: flex-start;
-webkit-justify-content: flex-start;
.cropper-content {
width: 350px;
height: 350px;
margin-right: 40px;
}
.preview-content {
.show-preview {
// border: 1px solid #ccc;
box-sizing: border-box;
width: 150px;
height: 150px;
overflow: hidden;
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
.preview {
overflow: hidden;
border-radius: 50%;
border: 1px solid #cccccc;
background: #fff;
margin-left: 0px;
}
}
.desc {
margin-top: 10px;
text-align: center;
}
.el-button {
margin: 10px 40px;
}
}
}
// 2.操作按钮区域
.btn-content {
width: 350px;
margin: 10px 20px;
text-align: center;
// #uploads {
// position: absolute;
// clip: rect(0 0 0 0);
// }
.btn {
height: 32px;
width: 32px;
font-size: 20px;
margin: 3px 5px;
background-color: #fff;
border: 1px solid #999;
border-radius: 4px;
}
}
}
.btn-footer {
width: 100%;
text-align: right;
padding-right: 20px;
margin-top: -20px;
}
}
}
</style>
参考文章
更多推荐
所有评论(0)