:组件中api 项目中用到的 ,各位根据各自进行更换
1:主要上传组件代码
<template>
<div class='upload'>
<el-upload ref='upload' :class='{has: isShowHasClass, unshow: hideUploadList}'
:action='api' :headers='headers' :file-list='fileList' :limit='limit' :accept='accept' :multiple='multiple' :list-type='listType' :disabled='disabled'
:on-preview='handlePictureCardPreview' :on-remove='handleRemove' :before-upload='checkImage' :on-change="uploadChange" :on-exceed="checkExceed"
:on-success='uploadSuccess' :on-error='uploadFail'>
<i class='el-icon-plus' v-if='listType == "picture-card"'></i>
<el-button type='primary' v-else>{{ text }}</el-button>
</el-upload>
</div>
</template>
<script>
import {mapActions} from 'vuex'
import {loadPreviewPlugin, previewImage} from 'utils'
import {isArrayFn} from 'utils/variable'
export default {
props: {
disabled: {
type:Boolean,
default:false,
},
isUpdateUrl: {
type: Boolean,
default: false,
},
value: {
type: String | Array,
default: () => [],
},
url: {
type: String | Array,
default: () => [],
},
type: {
type: String,
default: 'image',
},
unClick: {
type: Boolean,
default: false,
},
isLyc: {
type: Boolean,
default: false,
},
multiple: {
type: Boolean,
default: false,
},
isHidedList: {
type: Boolean,
default: true,
},
richText: {
type: Boolean,
default: false,
},
isClear: {
type: Boolean,
default: false,
},
accept: {
type: String,
default: 'image/*',
},
size: {
type: [Number,String],
default: 1024, // 默认1024kb,即:1M;
},
text: {
type: String,
default: '选择图片',
},
limit: {
type: Number,
default: 1,
},
listType: {
type: String,
default: 'picture-card'
},
imageSize: {
type: String,
default: '',
},
imgType:{
type:String,
default:'book:cover'
}
},
data () {
return {
urlClone: this.value,
fileList: [],
headers: {'X-HB-Client-Type': 'shop-pc',},
loading: false,
excelData: {
header: null,
results: null
}
}
},
watch: {
value (nVal, oVal) {
// 监听父组件清空url的时候清空文件
if (nVal) return
this.clearFiles()
},
isUpdateUrl (nVal, oVal) {
// 弹框或tab切换类型不触发beforeMount,用该方式更新urlClone
if (!nVal) return
this.initFieldList()
},
},
computed: {
hideUploadList () {
return this.multiple && this.isHidedList
},
api () {
if(this.type == 'image') { // 图片
return '/restcollege/collegeadmin/v1/upload/images'
} else if (this.type == 'text' || this.type == 'xls') { // excel
return '/restcollege/collegeadmin/v1/upload/lyric'
} else if (this.type == 'audio') { // 音频
return '/restcollege/collegeadmin/v1/upload/audio'
} else if (this.type == 'bnl') { // 点读包:上传类型为'bnl', 'zip', 'rar', 'tar'
return '/restcollege/collegeadmin/v1/upload/bookbnl'
}else if (this.type=='bookImage'){ //小彼恩图片
this.headers={'X-HB-Client-Type': 'xiaobien-pc',}
return `/xiaobienapi/common/v1/upload/images/?imgType=${this.imgType}`
}
},
isShowHasClass () {
// 多张不去掉上传按钮
if (this.multiple) return false
// 单张判断是否已生成url
if (!this.value) return false
return this.value.length || this.urlClone.length
},
},
methods: {
...mapActions(['uploadFile']),
getImageList (fileList) {
return fileList.map(item => {
if (item.status != 'success') return ''
if (item.response) { // 新上传的图
return item.response.path
} else { // 以前上传的图
return item.url
}
})
},
clearFiles () {
this.$refs.upload.clearFiles()
},
handleRemove (file, fileList) {
let imagePathList = []
fileList.map((item, index) => {
if (item.uid == file.uid) {
fileList.splice(index, 1)
}
})
imagePathList = this.getImageList(fileList)
this.urlClone = []
this.$emit('update:value', imagePathList)
// 嵌套多层的情况手动更新数据
this.$emit('removeChange', imagePathList)
},
handlePictureCardPreview (file) {
// 图片预览
if(this.unClick || this.type != 'image' && this.type != 'bookImage') return
previewImage(file.path || file.url)
return false
},
uploadChange (e) {
this.$emit('uploadChange', e)
},
uploadFail (err, file, fileList) {
this.$message.error(`${JSON.parse(err.message).message},请重新上传`)
},
uploadSuccess (response, file, fileList) {
// 音频类
if (this.type == 'audio') {
if (response.size > this.size ) {
this.$message.error(`音频不能超过${this.size}M`)
return
}
this.$emit('update:value', {...response, name: file.name.split('.mp3')[0]})
return
}
// 富文本类
if(this.richText) {
this.$emit('asyncData', fileList)
return
}
// excel类
if(this.type == 'xls') {
this.$emit('update:value', response.path)
this.upload(file.raw)
return
}
if (this.type == 'image' ||this.type=='bookImage') {
// 图片类
let imageList = this.getImageList(fileList)
let imagePath
if (fileList.length == 1) {
// 单张直接返回图片地址
imagePath = imageList[0]
} else {
// 多张返回图片地址列表
imagePath = imageList
}
this.$emit('update:value', imagePath)
}
// 歌词文件
if (this.type == 'text') {
this.$emit('update:value', response.path)
}
// // 点读包文件
// if (this.type == 'bnl') {
// this.$emit('update:value', response.path)
// this.$emit('update:size', response.size)
// }
},
checkExceed (files, fileList) {
this.$message.error(`最多只能上传${this.limit}张`)
},
checkImage (file) {
let _this = this
//普通的判断可以用return false
// 获取文件尺寸,判断尺寸在不在规定范围之内
if(this.isLyc) {
if(file.name.split('.')[1].toLowerCase() != 'lrc') {
this.$message.error('请上传格式正确的歌词文件')
return false
}
}
if (!_this.imageSize) {
return true
}
return new Promise(function(resolve, reject) {
let reader = new FileReader()
let size = JSON.parse(_this.imageSize)
reader.readAsDataURL(file)
reader.onload = function(theFile) {
let image = new Image()
image.src = theFile.target.result
image.onload = function() {
if (file.size > _this.size * 1024 ) {
_this.$message.error(`${file.name}大小不对,请重新上传!`)
reject('图片大小不对')
return
}
if(size.width && size.height) {
const noSizeLimit = !this.height || !this.width
const rightSize = size.width == this.width && size.height == this.height
if (noSizeLimit || rightSize) {
file.width = size.width
file.height = size.height
resolve(file)
return
} else {
_this.$message.error(`${file.name}尺寸不对,请重新上传!`)
reject('图片尺寸不对')
return
}
}
if(!size.width || !size.height) {
if(size.width) {
if(size.width == this.width) {
file.width = size.width
resolve(file)
} else {
_this.$message.error(`${file.name}尺寸不对,请重新上传!`)
reject('图片尺寸不对')
}
} else {
if(size.height == this.height) {
file.height = size.height
resolve(file)
} else {
_this.$message.error(`${file.name}尺寸不对,请重新上传!`)
reject('图片尺寸不对')
}
}
}
}
}
})
},
generateData({ header, results }) {
this.excelData.header = header
this.excelData.results = results
this.$emit('uploaded', results)
// this.onSuccess && this.onSuccess(this.excelData)
},
handleDrop(e) {
e.stopPropagation()
e.preventDefault()
if (this.loading) return
const files = e.dataTransfer.files
if (files.length !== 1) {
this.$message.error('Only support uploading one file!')
return
}
const rawFile = files[0] // only use files[0]
if (!this.isExcel(rawFile)) {
this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files')
return false
}
this.upload(rawFile)
e.stopPropagation()
e.preventDefault()
},
handleDragover(e) {
e.stopPropagation()
e.preventDefault()
e.dataTransfer.dropEffect = 'copy'
},
handleUpload() {
this.$refs['excel-upload-input'].click()
},
handleClick(e) {
const files = e.target.files
const rawFile = files[0] // only use files[0]
if (!rawFile) return
this.upload(rawFile)
},
upload(rawFile) {
if (!this.beforeUpload) {
this.readerData(rawFile)
return
}
const before = this.beforeUpload(rawFile)
if (before) {
this.readerData(rawFile)
}
},
readerData(rawFile) {
this.loading = true
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = e => {
const data = e.target.result
const workbook = XLSX.read(data, { type: 'array' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const header = this.getHeaderRow(worksheet)
const results = XLSX.utils.sheet_to_json(worksheet)
this.generateData({ header, results })
this.loading = false
resolve()
}
reader.readAsArrayBuffer(rawFile)
})
},
getHeaderRow(sheet) {
const headers = []
const range = XLSX.utils.decode_range(sheet['!ref'])
let C
const R = range.s.r
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
/* find the cell in the first row */
let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
headers.push(hdr)
}
return headers
},
isExcel(file) {
return /\.(xlsx|xls|csv)$/.test(file.name)
},
initFieldList () {
// 传入的 value 的值为空或者为数组时获取原格式
// 传入的 value 为单张且有值时将string转为array格式
this.urlClone = (isArrayFn(this.value) || !this.value) ? this.value : [this.value]
// 已有图片的情况下初始化照片墙列表
if (this.urlClone && this.urlClone.length) {
this.fileList = this.urlClone.map(item => {
return {
name: item.name || item.audio_name || item,
url: item,
}
})
}
},
},
beforeMount () {
loadPreviewPlugin()
this.initFieldList()
},
}
</script>
<style lang='less' scoped>
.has {
margin-top: -3px;
:global(.el-upload--picture-card) {
display: none;
}
:global(.el-upload--) {
display: none;
}
}
.unshow {
:global(.el-upload-list--) {
display: none;
}
:global(.el-upload-list--picture) {
display: none;
}
}
</style>
网友评论