前提
在开始之前,需要先把element-ui
安排上
//方式1
npm i element-ui -S
//方式2
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
功能与效果
这是实现后的视图,主要实现多个窗口的上传与删除功能。窗口数量是固定的,窗口内的图片由遍历动态数据获取。
功能包括:
- 通过接口获取图片信息并将图片渲染在页面上
- 上传图片前只有满足格式与大小需求才能成功上传
- 删除图片,有确认弹框
开始
首先在data内定义一个pic数组来储存图片对象,假设你需要展示3个图片窗口,就定义三个对象。这里的id可以表示每个窗口的位置:
pic:[
{id:1,url:""},
{id:2,url:""},
{id:3,url:""},
]
//用于获取你点击按钮时你选择的窗口位置
loading:{
id:""
},
//这是为了在图片上传时添加一个加载样式,可用可不同
//用的时候需要在标签上加上v-loading="onloading"
onloading:false
这个实例中,我选择把图片放在<el-card>
内,你可以根据样式需求放在不同的地方。这里我把样式相关的代码给去掉了。下面是基本框架
<el-card
v-for="item in pic"
:key="item.id"
>
//存放图片的容器
<div class="image">
<img :src="item.url" />
</div>
//存放按钮的容器
<div class="btns">
<el-button @click="handleDelete(item)">删除</el-button>
<el-upload
:before-upload="beforeUpload"
//before-upload是upload上传文件之前的钩子,参数为上传的文件。这里我定义了一个beforeUpload函数
:http-request="uploadImage"
//http-request是upload的内置方法,可以自定义上传的实现,这里我定义了一个uploadImage函数
:show-file-list=false//这里表示是否显示文件列表
>
<el-button @click="changeId(item)">上传图片</el-button>
//为了获取用户点击按钮对应的窗口位置,这里添加了一个changeId方法
</el-upload>
</div>
</el-card>
函数编写
首先用接口获取图片数据
showlist(){
this.axios
.post(`url`
).then(res => {
if(res.data.Status===0){
this.pic=res.data.Data
//把接收到的数据赋值给pic,
}
}).catch(() =>{
this.$message.error('请求失败')
})
},
点击上传按钮指向窗口位置,即改变id——changeId
changeId(item){
this.loading.id=item.id
},
上传前检查格式与尺寸——beforeUpload,只要返回 false 或者返回 Promise 且被 reject,则停止上传 ,即不会调用上传接口。官方文档
beforeUpload(file) {
//要求图片必须为jpeg、png、jpg,你也可以根据官方文档来写
let self = this;
let testimg = /^image\/(jpeg|png|jpg)$/.test(file.type);
if (!testimg) {
self.$message.error("上传的图片必须是 JPG 格式或PNG格式!");
return false
}
//要求图片比例必须为16:9,这个判定的方法其实就是判断图片的宽高比,只要在一个范围内就认定为时16:9
const isSize = new Promise(function (resolve, reject) {
let _URL = window.URL || window.webkitURL;
let img = new Image();
img.onload = function () {
//宽高比赋值给check
let check = img.width / img.height;
let valid = check > 1.7 && check < 1.8;
valid ? resolve() : reject();
};
img.src = _URL.createObjectURL(file);
}).then(
() => {
return file;
},
() => {
this.$message.error("上传的图片比例必须为16:9!");
return Promise.reject();
}
);
return isSize;
},
调用图片上传接口——uploadImage。
uploadImage(image) {
//这里声明一个id是因为要判断你选择的是哪个图片窗口的按钮,上传的时候才会把图片放在指定窗口位置
let id=this.loading.id
let fd = new FormData()
//给imgFile赋值image.file
fd.append('imgFile', image.file)
this.onloading=true//进入了上传过程,把加载状态改为true就会有一个加载样式了
this.axios
.post(`url?id=${id}`, fd//这里我传入了窗口指定的id和fd对象
).then(res => {
if(res.data.Status===0){
this.onloading=false//进入了这里表示上传成功了,加载样式可以取消了
this.$message.success(res.data.Msg)
this.pic[id-1].url=res.data.Data//我的借口返回的是处理后的url地址,所以我需要将新地址赋值给pic指定窗口的url,这里[id-1]是因为id是从1开始算起的而pic数组是从0开始算起的
}
}).catch(() =>{
this.$message.error('上传失败,请重新上传')
this.onloading=false//即使上传失败,也要记得关掉加载样式
console.log('上传失败')
})
},
删除图片——handleDelete(item)
handleDelete(item){
//由于你要指定你删除的图片在哪个窗口,所以这里会声明一个id来代表窗口的位置,后面会作为参数返给后台
//可要可不要
let id=item.id
if(this.pic[cid-1].url==""){
this.$message.error('这里没有图片,你无法进行删除操作')
return false
}
//删除图片弹出确认框
this.$confirm('你确定要删除该图片吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.axios
.post(`url?id=${id}`//调用接口并把图片窗口位置传过去,后台才会指定你删哪一个窗口的图片
).then(res => {
if(res.data.Status===0){
this.$message.success(res.data.Msg)
this.showlist()//成功删除后需要重新调用接口,以保证数据是最新的
}
}).catch(() =>{
this.$message.error('请求错误')
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
最后记得在create钩子上调用showlist获取图片数据~
created() {
this.showlist();
},
OK,祝你一切顺利~