elUpload里的很多回调方法,对于同一个项目来说,很多都是共用的和重复的.所以针对自家项目稍微做了封装,
简单实现了:1.图片大小,数量限制和提示,2.超出数量隐藏上传按钮的功能.3.校验必填
不足:图片是立刻上传而不是确认后上传 ,比较占用资源,后续希望优化这部分.
代码:
<template>
<div>
<el-upload
accept="image/png, image/jpg, image/jpeg"
name="multipartFile"
list-type="picture-card"
multiple
:limit="limitNum"
:action="uploadApi"
:headers="headers"
:data="typeData"
:file-list="fileList"
:before-upload="beforeUpload"
:on-change="handleChange"
:on-exceed="handleExceed"
:on-success="handleSuccess"
:on-remove="handleRemove"
:on-error="handleError">
<i class="el-icon-plus addMore"></i>
</el-upload>
<p>只能上传jpg/png格式文件,文件不能超过50kb</p>
</div>
</template>
<script>
import {getAccessToken} from '@/utils'
import config from "@/config"
export default {
name: 'PictureUpload',
computed: {
headers() {
const token = getAccessToken()
return {
Authorization: token
};
},
},
watch: {
initPics(val){
this.picStr = val
this.initFileList()
}
},
other: { //深度观察对象
handler(val){
},
deep: true
},
props: {
limitNum: {
type: Number,
default: 1
},
limitSize: {
type: Number,
default: 3
},
uploadApi: {
type: String,
default: ""
},
typeData: {
type: Object,
default: null
},
initPics: {
type: String,
default: ""
}
},
data(){
return {
fileList: [],//当前页面显示的图片列表
picList: [], //用于保存符合格式的当前页面显示的图片列表
picStr: ""
}
},
methods: {
initFileList(){
const params = this.initPics
if (params.length > 0) {
this.fileList = params.split(";").map(value => {
return {url: url + value}
})
}
this.hideOrShowAddMoreIcon(this.fileList)
},
emitChange(){
this.$emit("onChange", this.picStr)
},
beforeUpload(file){
return this.checkBeforeUpload(file)
},
handleChange(file, fileList){
this.hideOrShowAddMoreIcon(fileList)
},
handleExceed(file, fileList){
this.$message({message: '最多上传' + this.limitNum + '张', type: "warning"})
},
handleSuccess(res, file, fileList){
let arr = []
let oldPicStr = this.picStr
arr.push(res.data.name)
arr.unshift(oldPicStr)
if (oldPicStr == "") {
this.picStr = arr.join(";").slice(1)
} else {
this.picStr = arr.join(";")
}
this.picList = arr
},
handleRemove(file, fileList){
let arr = []
fileList.forEach(element => {
let url = ''
if (typeof(element.response) != "undefined") {
url = element.response.data.name
} else {
url = element.url.split('=')[1]
}
if (url != undefined) {
arr.push(url)
}
})
this.picStr = arr.join(";")
this.picList = arr
this.hideOrShowAddMoreIcon(fileList)
},
handleError(err, file, fileList){
this.hideOrShowAddMoreIcon(fileList)
},
checkBeforeUpload(file){
const isJPGorPNG = file.type
const isLt = (file.size / 1024 / 1024) < this.limitSize
var flag = true
if (isJPGorPNG !== 'image/jpeg' && isJPGorPNG !== 'image/png') {
this.$message.error('上传图片只能是JPG或者PNG格式!')
flag = false
}
if (!isLt) {
this.$message({
showClose: true,
message: '图片: ' + file.name + ' 太大,请压缩后再上传!',
type: 'warning'
})
flag = false
}
return flag
},
hideOrShowAddMoreIcon(fileList){
let a = document.getElementsByClassName('addMore')[0]
if (a) {
let parentElement = a.parentNode
if (fileList.length >= this.limitNum) {
parentElement.style.display = "none"
} else {
parentElement.style.display = "inline-block"
}
}
this.emitChange()
}
}
}
</script>
其中,import 的是项目获取本地token;config里获取项目路径.如果是小白,可直接把这两个属性也绑定到props上,通过父传子的方法使用.
使用方法:
在父组件:
1.引入:import PictureUpload from 'components/PictureUpload'
2.组件:<el-form-item label="图片:" prop="pics">
<picture-upload
list-type="picture-card"
name="multipartFile"
accept="image/png, image/jpg, image/jpeg"
:limitNum="limitNum"
:typeData="typeData"
:uploadApi="uploadApi"
:initPics = "initPics"
@onChange="change"
></picture-upload>
</el-form-item>
3.change方法:
change(childValue){
this.form.pics = childValue // 回传给form表单的值
// this.$refs.form.validateField('pics') // 这里可以触发自己定义的必填校验
},
4.data(){
return{
limitNum:3,
initPics:"",
uploadApi: "http://xxxxx",
typeData: {type: 'topic'},
}
}
5.校验 rules: { pics: [ { required: true, validator: this.picCheck , trigger: 'blur'}]}
6.picCheck方法:
picCheck(rule,value,callback){ //方法内规则可以自定义
if(this.form.pics.trim().length>0){ //至少上传一张校验
callback()
}else{
callback(new Error('请上传至少一张图片!'));
}
}