最近写了一个后台管理项目,发现每个后台项目都离不开上传图片,决定把上传图片做个封装,话不多说直接上代码!
组件 upload 代码块
代码语言:javascript复制<template>
<div>
<el-upload
:action="action"
ref="upload"
list-type="picture-card"
accept="image/*"
:class="{hide:WhetherUpload||isShowUpload}"
:limit="imgLimit"
:file-list="fileList"
:multiple="isMultiple"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:on-exceed="handleExceed"
:on-error="imgUploadError"
>
<i 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 v-if="removeIco" class="el-upload-list__item-delete" @click="handleRemove(file,fileList)" >
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
export default {
name: 'upload',
//子组件通过 props方法获取父组件传递过来的值
props: {
action:{type:String},//action请求地址
imgLimit:{type:Number,default: 1},//设置上传数量
fileSize:{type:Number,default: 2},//设置图片大小
fileListStr:'',//查看已上传图片
removeIco:{type:Boolean,default:true},//是否显示删除按钮
operationType:{type:Boolean,default:true},//刷新页面
isShowUpload:{type:Boolean,default:false},//是否显示上传操作
},
data() {
return {
dialogImageUrl: '',
dialogVisible: false,
isMultiple: true,
imgList:[],
WhetherUpload:false,//是否显示上传操作
fileList:[]
}
},
//通过watch来监听message是否改变
watch:{
'operationType':function(){
// console.log(this.operationType)
this.WhetherUpload = this.fileList.length >= this.imgLimit;
}
},
// 创建完毕状态(里面是操作)
created() {
this.fileList=this.imageConversion(this.imgLimit,this.fileListStr);
this.WhetherUpload = this.fileList.length >= this.imgLimit;
},
/**
* 里面的方法只有被调用才会执行
*/
methods: {
//移除图片
handleRemove(file, fileList) {
console.log(fileList);
for (let index = 0; index < fileList.length; index ) {
if(fileList[index].uid==file.uid){
this.fileList.splice(index,1) //移除数组中要删除的图片
}
}
this.WhetherUpload = this.fileList.length >= this.imgLimit;
this.$emit('getImgList',this.fileList);
},
//预览图片时调用
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
//文件上传之前调用做一些拦截限制
beforeAvatarUpload(file) {
const isJPG = true;
const isLt2M = file.size / 1024 / 1024 < this.fileSize;
// if (!isJPG) {
// this.$message.error('上传头像图片只能是 JPG 格式!');
// }
if (!isLt2M) {
this.$message.error('上传图片大小不能超过 ' this.fileSize 'MB!');
}
return isJPG && isLt2M;
},
//图片上传成功
handleAvatarSuccess(res, file,fileList) {
console.log("图片上传")
console.log(fileList);
console.log(file);
this.imgList=fileList;
// this.imageUrl = URL.createObjectURL(file.raw);
this.$emit('getImgList',fileList);
this.WhetherUpload = fileList.length >= this.imgLimit;
// console.log(this.imgList)
// console.log(this.WhetherUpload)
},
//图片上传超过数量限制
handleExceed(files, fileList) {
this.$message.error('上传图片不能超过' this.imgLimit '张!');
// console.log(files, fileList);
this.imgList=fileList;
this.$emit('getImgList',this.imgList);
},
//图片上传失败调用
imgUploadError(err, file, fileList){
console.log(file);
console.log(fileList);
console.log(err)
this.$message.error('上传图片失败!');
this.$emit('getImgList',fileList);
this.WhetherUpload = fileList.length >= this.imgLimit;
},
/**
* 处理获取服务地址转成本地查看
* type:图片数量
* parameter:图片参数
*/
imageConversion:function(type,parameter){
console.log(parameter)
let imgList=[];
if(type>1){
if(parameter){
for (let i = 0; i < parameter.length; i ) {
let img={
url:parameter[i],
response:'',
}
imgList.push(img);
}
}
return imgList;
}else{
if(parameter){
let img={
url:parameter,
response:'',
}
imgList.push(img);
}
return imgList;
}
},
}
}
</script>
<style>
.hide .el-upload--picture-card {
display: none;
}
</style>
页面使用
<upload :action="this.$picture" :key="refresh" :fileListStr="this.ruleForm.bootPage"
@getImgList="(val)=>{this.ruleForm.bootPage=this.uploadPictureParameters(1,val)}"></upload>
this.$picture是上传图片的地址,我这里是把地址挂载到vue的实例上了,目的是为了以后维护方便
代码语言:javascript复制<template>
<div>
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>启动页</el-breadcrumb-item>
</el-breadcrumb>
<el-card class="box-card">
<el-table :data="bannerList" style="width: 100%">
<el-table-column type="index" align="center" label="序号" width="200"></el-table-column>
<el-table-column align="center" label="图片">
<template slot-scope="scope">
<img class="showImg" :src="scope.row.data" alt />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200">
<template slot-scope="scope">
<el-button @click="handRedact(scope.row.data)" type="primary" size="small">编辑</el-button>
<el-button @click="handleClick(scope.row.data)" type="danger" size="small">详情</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog
title="编辑"
:visible.sync="dialogVisible"
width="35%"
:before-close="handleClose">
<el-form
:model="ruleForm"
:rules="rules"
:key="dialogVisible"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm">
<el-form-item label="图片" prop="bootPage">
<upload
:action="this.$picture"
:key="refresh"
:fileListStr="this.ruleForm.bootPage"
@getImgList="(val)=>{this.ruleForm.bootPage=this.uploadPictureParameters(1,val)}"
></upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="bootPageBtn('ruleForm')">确定</el-button>
<el-button @click="resetForm('ruleForm')">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<el-dialog
title="详情"
:visible.sync="dialogVisibleBoot"
width="50%">
<img class="bootPageImg" :src="bootPageImg" alt="">
</el-dialog>
</div>
</template>
<script>
import upload from '../../components/Upload'
export default {
components: {
upload
},
data () {
return {
dialogVisible:false,
dialogVisibleBoot:false,
bannerList:[],
bootPageImg:"",
ruleForm: {
bootPage: "", //轮播图地址
},
rules: {
bootPage: [
{ required: true, message: "请上传启动页", trigger: "blur" }
]
},
refresh:0
}
},
created () {
this.findBootPage()
},
methods: {
async findBootPage(){
let {data:res}=await this.$http.post('config/findBootPage')
console.log(res);
if (res.code==200) {
this.bannerList.push(res)
}
},
handRedact(e){
this.dialogVisible=true
console.log(e);
this.ruleForm.bootPage=e
},
handleClick(e){
this.dialogVisibleBoot=true
this.bootPageImg=e
},
handleClose(){
this.dialogVisible=false
},
bootPageBtn(formName) {
this.$refs[formName].validate(async(valid) => {
if (valid) {
console.log("123");
let {data:res}=await this.$http.post('config/updateBootPage',{bootPage:this.ruleForm.bootPage})
console.log(res);
if (res.code==200) {
this.dialogVisible=false
this.bannerList=[]
this.findBootPage()
this.$message.success(res.message)
}else{
this.$message.error(res.message)
}
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.dialogVisible=false
},
/**
* 处理本地上传图片时所需参数
* type:图片类型
* parameter:图片上传集合
*/
uploadPictureParameters: function (type, parameter) {
let imgList = [];
let img = "";
if (type > 1) {
if (parameter.length > 0) {
for (let i = 0; i < parameter.length; i ) {
if (parameter[i].response) {
imgList.push(parameter[i].response.data.imgUrl);
} else {
imgList.push(parameter[i].url);
}
}
}
this.refresh = 1;
return imgList;
} else {
if (parameter.length > 0) {
this.refresh = 1;
// this.ruleForm.imgUrl = parameter[0].response.data.imgUrl;
return (img = parameter[0].response.data.imgUrl);
}
this.refresh = 1;
return;
}
},
}
}
</script>
<style lang="scss" scoped>
.box-card{
margin-top: 20px;
.showImg{
width: 100;
height: 100px;
}
}
/deep/ .el-dialog__footer{
text-align: left;
}
.bootPageImg{
display: block;
margin: auto;
}
</style>
如果哪点不懂可以留言,也希望大佬指点一二。