最近使用Vue作图片的上传,以及图片的列表展示功能,并且可以对图片进行放大预览处理,这里做一下记录总结,方便以后使用。
下面的代码,笔者基于Vue.js,使用了element-ui组件类库实现的,功能包括:支持图片的上传
、图片类型以及图片大小校验
、图片列表展示
、图片大图预览功能
、图片空白处点击关闭大图
功能。
废话不多说了,直接上代码:
<template>
<div class="app-container">
<el-tooltip slot="left" class="item" effect="dark" content="点击查看效果" placement="top-start">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="openModel"/>
</el-tooltip>
<!--表单组件-->
<el-dialog
:close-on-click-modal="true"
:close-on-press-escape="true"
:visible.sync="modelFlag"
title="model弹框"
width="50%"
:fullscreen="false"
>
<el-form ref="formData" :inline="true" :model="formData" size="small"
label-width="140px">
<el-form-item label="file1" style="width: 500px;">
<el-upload
class="avatar-uploader"
name="file"
:action="uploadUrl"
list-type="picture"
:show-file-list="false"
:on-preview="(file)=>handlePreview(file,'file1')"
:on-remove="(file,fileList)=>handleRemove(file,fileList,'file1')"
:on-success="(response, file)=> handleUploadSuccess(response, file,'file1')"
:before-upload="beforeUpload"
>
<el-tooltip class="item" effect="dark" content="点击修改附件" placement="right">
<img style="width: 250px;height:120px" v-if="formData.file1" :src="formData.file1" class="avatar" alt="">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-tooltip>
</el-upload>
</el-form-item>
<!--第一种方式:点击右下角加号会放大图片-->
<el-image v-show="formData.file1"
@click.native="handleClickItem"
src="https://img0.baidu.com/it/u=1713870962,188032507&fm=26&fmt=auto&gp=0.jpg"
:preview-src-list="[formData.file1]"
fit="fill"
class="el-avatar"
/>
<el-divider></el-divider>
<el-form-item label="file2" style="width: 500px;">
<el-upload
class="avatar-uploader"
style="width: 250px;height:130px"
:action="uploadUrl"
:on-preview="(file)=>handlePreview(file,'file2')"
:on-remove="(file,fileList)=>handleRemove(file,fileList,'file2')"
:on-change="handleChange"
:on-success="(response, file)=> handleUploadSuccess(response, file,'file2')"
:file-list="showFileList.file2"
:before-upload="beforeUpload"
:limit="parseInt(1)"
list-type="picture">
<el-button v-show="formData.file2 === null || formData.file2 === ''" size="small" type="primary">
点击上传
</el-button>
</el-upload>
</el-form-item>
<!--第二种方式:点击图片会放大预览图片-->
<el-image-viewer v-if="file2BigFlag"
:on-close="()=>closePicturePreview('file2')"
@click.native="handleClickItem"
:url-list="[formData.file2]"/>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="success" @click="closeModel">取消</el-button>
<el-button type="primary" @click="confirmSubmit">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import apis from '@/store/modules/api'
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
export default {
name: 'ImageFileUpload',
components: {ElImageViewer},
data() {
return {
modelFlag: false,
formData: {
//表单里附件数据
'file1': null,
'file2': null,
},
//附件展示(这里列表需要展示name和url属性,这里单独维护,方便处理)
showFileList: {},
//预览大图片标识,一般附件列表展示的看不清楚,会对图片进行放大处理
file1BigFlag: false,
file2BigFlag: false,
//上传附件的url地址
uploadUrl: `url`,
}
},
methods: {
/**
* 打开model框,获取数据并赋值展示的附件列表
*/
openModel(params) {
//获取数据源
this.formData.file1 = 'https://img0.baidu.com/it/u=3153405721,1524067674&fm=26&fmt=auto&gp=0.jpg';
this.formData.file2 = 'https://img1.baidu.com/it/u=1474266791,210202337&fm=26&fmt=auto&gp=0.jpg';
if (this.formData.file2) {
this.showFileList.file2 = [{name: 'file2.jpeg', url: this.formData.file2}]
}
this.modelFlag = true
},
closeModel() {
this.modelFlag = false
},
confirmSubmit() {
this.$confirm('您确认提交吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
console.log(JSON.stringify(this.formData))
}).catch(() => {
})
},
/**
* 附件上传成功后的处理
*/
handleUploadSuccess(res, file, type) {
if (type && type === 'file2') {
this.formData.file2 = res.data.url
//附件展示
this.showFileList.file2 = [{name: 'file2.jpeg', url: this.formData.file2}]
} else if (type && type === 'file1') {
this.formData.file1 = res.data.url
this.showFileList.file1 = [{name: 'file1.jpeg', url: this.formData.file1}]
}
},
/**
* 附件上传前的前置校验
* @param file
* @returns {boolean}
*/
beforeUpload(file) {
const fileTypeFlag = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg'
const fileTenM = file.size / 1024 / 1024 < 10
if (!fileTypeFlag) {
this.$message.error('上传附件格式只支持png、jpg、jpeg类型!')
}
if (!fileTenM) {
this.$message.error('上传附件大小不能超过10MB!')
}
return fileTypeFlag && fileTenM
},
handleRemove(file, fileList, type) {
//这个方法在上传文件时也会触发,所以这里做一下判断,只有主动删除文件才会触发
if (file && file.status && file.status === 'ready') {
return
}
if (type && type === 'file2') {
this.formData.file2 = null
this.showFileList.file2 = []
} else if (type && type === 'file1') {
this.formData.file1 = null
this.showFileList.file1 = []
}
},
/**
* 点击文件列表中已上传的文件时的钩子(预览大图)
*/
handlePreview(file, type) {
if (type && type === 'file2') {
this.file2BigFlag = true
} else if (type && type === 'file1') {
this.file1BigFlag = true
}
},
/**
* 预览图片关闭时事件
*/
closePicturePreview(type) {
if (type && type === 'file2') {
this.file2BigFlag = false
} else if (type && type === 'file1') {
this.file1BigFlag = false
}
},
handleChange(file) {
console.log('handleChange' + file)
},
/**
* 用户点击遮罩层关闭预览大图也是习惯性的常规操作,但 elementUI 并没有支持。
两种思路:
1、把hide事件绑定在遮罩层 dom
2、直接调用 关闭按钮 上的 click 事件
获取遮罩层dom很容易,hide事件就相对麻烦了,需要获取 vue实例子组件 image-viewer,再访问子组件的method。所以我使用了第二种方法
*/
handleClickItem() {
this.$nextTick(() => {
// 获取遮罩层dom
let domImageMask = document.querySelector('.el-image-viewer__mask')
if (!domImageMask) {
return
}
// 添加click监听事件,点击遮罩层时调用关闭按钮的 click 事件
domImageMask.addEventListener('click', () => {
document.querySelector('.el-image-viewer__close').click()
})
})
},
}
}
</script>
<style scoped>
/deep/ .el-image-viewer__close {
color: white;
}
/*控制加号样式*/
/deep/ .el-image {
width: 25px;
height: 25px;
}
/*控制预览图片大小*/
/deep/ .el-image-viewer__img {
height: 400px;
width: 500px;
}
/deep/ .el-avatar {
display: flex;
position: absolute;
left: 385px;
top: 175px;
color: white;
}
/deep/ .el-upload-list--picture {
margin-top: -30px;
}
/deep/ .el-upload-list--picture .el-upload-list__item.is-success {
width: 250px;
height: 120px;
}
/deep/ .el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name {
line-height: 80px;
margin-top: 0;
margin-left: 3px;
}
.avatar-uploader-icon {
border: 1px dashed #d9d9d9;
border-radius: 6px;
position: relative;
overflow: hidden;
display: inline-block;
cursor: pointer;
outline: white;
font-size: 40px;
color: #8c939d;
width: 60px;
height: 60px;
}
.el-icon-plus:before {
text-align: center;
vertical-align: middle;
}
</style>
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!
给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!