web端項目中有一個上傳圖片的功能石抡,但是element-ui提供的上傳插件都不能滿足的我的需要,dropzone也因為我們框架封裝的原因拯勉,在重置和初始化時都有一些問題蚁滋。在研究dropzone的問題上花費了很多時間,最后也沒解決耘斩,就索性自己寫了一個沼填。
整理思路
功能方面:
1、上傳圖片括授,那肯定是input,type=“file”
2岩饼、獲取圖片荚虚,監(jiān)聽input的change事件
3、拿到圖片上傳
頁面樣式:
1籍茧、展示一個虛線框版述,沒有圖片時中間顯示一個+號,點擊選擇圖片寞冯;
2渴析、有圖片時展示圖片,鼠標(biāo)懸浮在圖片上方時顯示移除按鈕吮龄,否則不展示移除按鈕
代碼如下:
<template>
<div class="dropzone">
<input ref="uploadInput"
type="file"
name="file"
value=""
accept="image/gif,image/jpeg,image/jpg,image/png"
@change="selectImg($event)">
<div :class="operationShow?'operation-div':'operation-div hide'">
<img :src="defaultImg">
<span class="remove"
@click="remove">移除</span>
</div>
<div :class="operationShow?'txt hide':'txt'">
+
</div>
</div>
</template>
<script>
export default {
props: {
url: {
default: "",
type: String
},
imgSrc: {
default: "",
type: String
},
autoUpload: {
default: true,
type: Boolean
}
},
data()
{
return {
operationShow: false,
uploadFile: "",
defaultImg: process.env.BASE_API + "/service-admin/" + this.imgSrc
};
},
watch: {
imgSrc(newsVal, oldVal)
{
this.init(newsVal);
}
},
mounted()
{
this.init(this.imgSrc);
},
methods: {
//選擇圖片
selectImg(e)
{
const imgFile = e.target.files[0];
if (imgFile)
{
this.uploadFile = imgFile;
let reader = new FileReader();
reader.readAsDataURL(imgFile);
reader.onload = (event) =>
{
this.defaultImg = reader.result;
this.operationShow = true;
if (this.autoUpload)
{
this.upload();
}
};
}
},
upload()
{
//將圖片轉(zhuǎn)成FormData類型數(shù)據(jù)
let formData = new FormData();
formData.append("file", this.uploadFile);
///通知父級上傳圖片
this.$emit("uploadImg", formData);
},
remove()
{
// 圖片設(shè)為空
this.defaultImg = "";
// 隱藏圖片層俭茧,展示選擇圖片層
this.operationShow = false;
//通知父級移除圖片
this.$emit("removeImg");
},
init(data)
{
//圖片不為空時,顯示圖片層并展示圖片漓帚,input層隱藏
if (data !== undefined && data !== "" && data !== null)
{
this.operationShow = true;
this.defaultImg = process.env.BASE_API + "/" + data;
}
else
{
//圖片為空時母债,不顯示圖片層,顯示input層
this.defaultImg = "";
this.operationShow = false;
}
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss" >
@mixin base{
position: absolute;
top: 5%;
height: 100%;
width: 100%;
}
.dropzone{
position: relative;
height: 200px;
max-width: 200px;
width:100%;
border: 1px dashed #ccc;
box-sizing: border-box;
input{
@include base;
opacity: 0;
z-index: 10;
}
.operation-div{
@include base;
z-index: 100;
text-align: center;
img{
width: 80%;
height: 80%;
}
&:hover>.remove{
display: block;
}
.remove{
display: block;
height: 10%;
width: 100%;
display: none;
text-align: center;
cursor: pointer;
}
.remove:hover{
color: #409EFF;
}
}
.txt{
position: absolute;
width: 100%;
height: 30px;
font-size: 40px;
line-height: 30px;
top: 50%;
transform: translateY(-50%);
text-align: center;
color: #aaa;
z-index: 1;
}
.hide{
display: none;
}
}
</style>
在父組件中使用:
<el-form-item
label="圖片"
prop="pic">
<form-upload-image
:auto-upload="true"
:img-src="form.data.pic" // form表單的數(shù)據(jù)
@uploadImg="uploadImg"
@removeImg="removeImg"/>
</el-form-item>
// 上傳圖片
uploadImg(formData)
{
//手動校驗圖片輸入框
this.$refs["dataForm"].validateField("pic");
//使用axios上傳圖片尝抖,repo是自己寫的axios攔截器
new Repo({
url: 'url',
method: "post",
data: formData,
headers: { "Content-Type": "multipart/form-data" }
}).then((response) =>
{
// 上傳成功毡们,清空校驗信息
this.$refs["dataForm"].clearValidate("pic");
//修改form data數(shù)據(jù)
this.form.data.pic = response.data[0];
});
},
// 移除圖片
removeImg()
{
//修改form data數(shù)據(jù)
this.form.data.pic = "";
//手動校驗圖片輸入框
this.$refs["data-form"].$refs["default"].validateField("pic");
}