文章资料:https://www.cnblogs.com/ljx20180807/p/10839713.html
实际上我们只需要一段代码:
<input ref="file" type="file" accept="image/*" capture="user">
加亿点细节:预览图片、限制图片个数、删除图片、相同图片文件判断、图片大小判断。
预览图片这里使用的是viewer组件。
1.安装依赖
npm install v-viewer
2.配置在man.js中
import 'viewerjs/dist/viewer.css'
import Viewer from 'v-viewer'
import Vue from 'vue'
Vue.use(Viewer)
3.页面代码
文章资料:https://blog.csdn.net/ccc_cccc_ccc/article/details/106334012
<template>
<!-- 新建时可以进行图片的新增和删除。修改时只能展示之前上传的图片,点重新上传会将之前上传的图片清空,之后可以进行重新上传图片的新增和删除 -->
<div class="img-group" v-if="isInsert">
<span class="control-label">上传图片</span>
<span class="help-block">(建议图片格式为:JPEG/BMP/PNG/GIF,大小不超过5M,最多可上传5张)</span>
<div class="control-form">
<ul class="upload-imgs">
<li v-if="imgLen>=5 ? false : true">
<input
type="file"
class="upload"
@change="addImg"
ref="inputer"
multiple
accept="image/png, image/jpeg, image/gif, image/jpg"
/>
<a class="add">
<i class="iconfont icon-plus"></i>
<p>点击上传</p>
</a>
</li>
<li v-for="(value, key) in imgs" :key="key">
<div class="imgBox">
<p class="img">
<viewer :images="images">
<img :src="getObjectURL(value)" />
</viewer>
<a class="close" @click="delImg(key)">×</a>
</p>
<div class="picName">{
{value.name}}</div>
</div>
</li>
</ul>
</div>
</div>
<div class="img-group" v-else style="margin-left: 35px;">
<span class="control-label">重新上传图片</span>
<span class="help-block">(重新上传会覆盖之前图片!建议图片格式为:JPEG/BMP/PNG/GIF,大小不超过5M,最多可上传5张)</span>
<div class="control-form">
<ul class="upload-imgs" style="margin: 10px 0 30px 51px;">
<li v-if="imgLen>=5 ? false : true">
<input
type="file"
class="upload"
@change="addImg"
ref="inputer"
multiple
accept="image/png, image/jpeg, image/gif, image/jpg"
/>
<a class="add">
<i class="iconfont icon-plus"></i>
<p>点击重新上传</p>
</a>
</li>
<template v-if="!isReUpload">
<li v-for="(value, key) in reImgs" :key="key">
<div class="imgBox">
<p class="img">
<viewer :images="images">
<img :src="value" />
</viewer>
</p>
</div>
</li>
</template>
<template v-else>
<li v-for="(value, key) in imgs" :key="key">
<div class="imgBox">
<p class="img">
<viewer :images="images">
<img :src="getObjectURL(value)" />
</viewer>
<a class="close" @click="delImg(key)">×</a>
</p>
<div class="picName">{
{value.name}}</div>
</div>
</li>
</template>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
formData: new FormData(),
imgs: {
}, // 循环生成的li的数据来源
imgLen: 0, // 上传图片的数量
isInsert: true, // 判断是否为新增
reImgs: [], // 详情传来的img的url
isReUpload: false, // 重新上传
images: [], // 详情预览大图数组
};
},
methods: {
addImg(event) {
this.isReUpload = true
this.reImgs = []
let inputDOM = this.$refs.inputer;
// 通过DOM取文件数据
this.fil = inputDOM.files;
let oldLen = this.imgLen;
let len = this.fil.length + oldLen;
if (len > 5) {
alert("最多可上传5张,您还可以上传" + (5 - oldLen) + "张");
return false;
}
for (let i = 0; i < this.fil.length; i++) {
let size = Math.floor(this.fil[i].size / 1024);
if (size > 5 * 1024 * 1024) {
alert("请选择5M以内的图片!");
return false;
}
if (this.fil[i].name in this.imgs) {
alert("该文件已上传,请重新选择!")
} else {
this.imgLen++;
this.$set(this.imgs, this.fil[i].name, this.fil[i]);
}
//解决 input type=”file“ 相同文件change事件只执行一次的问题
this.$refs.inputer.value = null;
}
},
getObjectURL(file) {
var url = null;
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
},
delImg(key) {
this.$delete(this.imgs, key);
this.imgLen--;
},
},
}
</script>
<style >
.img-group {
margin-left: 63px;
margin-top: 30px;
font-size: 14px;
color: #606266;
font-weight: 700;
.control-label {
margin-right: 12px;
}
.control-form {
margin-top: 30px;
}
}
.upload-imgs {
margin: 10px 0 30px 22px;
overflow: hidden;
font-size: 0;
}
.upload-imgs li {
position: relative;
width: 168px;
height: 188px;
font-size: 14px;
display: inline-block;
padding: 10px;
margin-right: 25px;
border: 2px dashed #ccc;
text-align: center;
vertical-align: middle;
input {
opacity: 0;
}
}
.upload-imgs .add {
display: block;
background-color: #ccc;
color: #ffffff;
height: 50px;
padding: 10px 0;
p {
font-size: 20px;
line-height: 83px;
}
}
.upload-imgs .add .iconfont {
padding: 10px 0;
font-size: 40px;
}
.upload-imgs li .upload {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 168px;
height: 168px;
}
.upload-imgs .img {
position: relative;
width: 144px;
height: 144px;
line-height: 144px;
margin: 0;
}
.upload-imgs .img img {
width: 144px;
height: 144px;
vertical-align: middle;
}
.upload-imgs li .img .close {
display: block;
position: absolute;
right: -6px;
top: -14px;
line-height: 1;
font-size: 26px;
color: rgb(211, 23, 23);
font-weight: 400;
}
.imgBox {
position: relative;
}
.picName {
position: absolute;
left: 8px;
bottom: -27px;
line-height: 1.5;
font-size: 14px;
max-width: 130px;
color: #606266;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
效果:
修改细节,只需拍一张照片,数量限制为1,使用图标代替按钮。
<li class="addImage" v-if="imgLen>=1 ? false : true">
//隐藏input
<input
type="file"
class="upload"
@change="addImg"
capture="user"
ref="inputer"
multiple
style="display:none"
accept="image/png, image/jpeg, image/gif, image/jpg"
/>
//使用iview的相机图标
<Icon style="margin-top: 34px;" type="ios-camera" size="66" @click="choiceImg"/>
</li>
在script中添加方法 点击图标调用input。
methods:{
choiceImg(){
this.$refs.inputer.dispatchEvent(new MouseEvent('click'))
},
}
效果:
4.处理图片
处理部分手机拍照图片方向会变为横向的问题。(待做)
查找资料后发现需要转base64,利用Exif获取图片的方向,并进行旋转角度,这样会导致Viewer 无效,因为图片路径变成了base64,其无法解析图片。你可以转回图片文件然后显示。
5.上传图片
5.1 上传
错误记录:文件上传之transformRequest配置导致其他接口错误
根据文章配置后直接调用。
最后效果
页面修改后代码:
<template>
<div class="img-group" v-if="isInsert">
<span class="control-label">上传图片</span>
<span class="help-block">(建议图片格式为:JPEG/BMP/PNG/GIF,大小不超过5M,最多可上传1张)</span>
<div class="control-form">
<ul class="upload-imgs">
<li class="addImage" v-if="imgLen>=1 ? false : true">
<!-- //隐藏input -->
<input
type="file"
class="upload"
@change="addImg"
capture="user"
ref="inputer"
multiple
style="display:none"
accept="image/png, image/jpeg, image/gif, image/jpg"
/>
<!-- //使用iview的相机图标 -->
<Icon style="margin-top: 34px;" type="ios-camera" size="66" @click="choiceImg"/>
</li>
<li v-for="(value, key) in imgs" :key="key">
<div class="imgBox">
<p class="img">
<viewer :images="images">
<img :src="getObjectURL(value)" />
</viewer>
<a class="close" @click="delImg(key)">×</a>
</p>
<div class="picName">{
{value.name}}</div>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
formData: new FormData(),
imgs: {
}, // 循环生成的li的数据来源
imgLen: 0, // 上传图片的数量
isInsert: true, // 判断是否为新增
reImgs: [], // 详情传来的img的url
isReUpload: false, // 重新上传
images: [], // 详情预览大图数组
};
},
methods: {
choiceImg(){
this.$refs.inputer.dispatchEvent(new MouseEvent('click'))
},
addImg(event) {
this.isReUpload = true
this.reImgs = []
let inputDOM = this.$refs.inputer;
// 通过DOM取文件数据
this.fil = inputDOM.files;
let oldLen = this.imgLen;
let len = this.fil.length + oldLen;
if (len > 1) {
alert("最多可上传1张,您还可以上传" + (1 - oldLen) + "张");
return false;
}
for (let i = 0; i < this.fil.length; i++) {
let size = Math.floor(this.fil[i].size / 1024);
if (size > 5 * 1024 * 1024) {
alert("请选择5M以内的图片!");
return false;
}
if (this.fil[i].name in this.imgs) {
alert("该文件已上传,请重新选择!")
} else {
this.imgLen++;
this.$set(this.imgs, this.fil[i].name, this.fil[i]);
//上传
this.addRecord(this.fil[i])
}
//解决 input type=”file“ 相同文件change事件只执行一次的问题
this.$refs.inputer.value = null;
}
},
getObjectURL(file) {
var url = null;
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) {
// mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
},
delImg(key) {
this.$delete(this.imgs, key);
this.imgLen--;
},
addRecord(imgs){
console.info(imgs)
alert(this.getObjectURL(imgs))
var self=this
var formData=new FormData();// 创建form对象
formData.append('userfile',imgs);
// 通过append向form对象添加数据,可以通过append继续添加数据
formData.append('name',imgs.name);
self.$ajax.POSTFILE(
"/inspectorAdmin/addImg",
formData
).then((data)=>{
console.log(data)
if(data){
self.$Message.success('新增成功');
}
else{
self.$Message.error('新增失败');
}
}
)
},
},
}
</script>
<style >
.img-group {
margin-left: 63px;
margin-top: 30px;
font-size: 14px;
color: #606266;
font-weight: 700;
.control-label {
margin-right: 12px;
}
.control-form {
margin-top: 30px;
}
}
.upload-imgs {
margin: 10px 0 30px 22px;
overflow: hidden;
font-size: 0;
}
.upload-imgs li {
position: relative;
width: 168px;
height: 188px;
font-size: 14px;
display: inline-block;
padding: 10px;
margin-right: 25px;
border: 2px dashed #ccc;
text-align: center;
vertical-align: middle;
input {
opacity: 0;
}
}
.upload-imgs .add {
display: block;
background-color: #ccc;
color: #ffffff;
height: 50px;
padding: 10px 0;
p {
font-size: 20px;
line-height: 83px;
}
}
.upload-imgs .add .iconfont {
padding: 10px 0;
font-size: 40px;
}
.upload-imgs li .upload {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 168px;
height: 168px;
}
.upload-imgs .img {
position: relative;
width: 144px;
height: 144px;
line-height: 144px;
margin: 0;
}
.upload-imgs .img img {
width: 144px;
height: 144px;
vertical-align: middle;
}
.upload-imgs li .img .close {
display: block;
position: absolute;
right: -6px;
top: -14px;
line-height: 1;
font-size: 26px;
color: rgb(211, 23, 23);
font-weight: 400;
}
.imgBox {
position: relative;
}
.picName {
position: absolute;
left: 8px;
bottom: -27px;
line-height: 1.5;
font-size: 14px;
max-width: 130px;
color: #606266;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>