Vue中图片上传组件封装-antd的a-upload二次封装-案例
Posted JackieDYH
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue中图片上传组件封装-antd的a-upload二次封装-案例相关的知识,希望对你有一定的参考价值。
a-upload组件
api
const publicApi =
UploadImage: '/common/uploadImage',
DeleteImage: '/common/deleteImage',
/**
* 上传图片
* @param * parameter
* @returns
*/
export function UploadImage(parameter)
return request(
url: publicApi.UploadImage,
method: 'post',
data: parameter
)
/**
* 删除图片 :name
* @param * parameter
* @returns
*/
export function DeleteImage(parameter)
return request(
url: `$publicApi.DeleteImage/$parameter`,
method: 'delete'
// params: parameter
)
组件封装
<template>
<div class="upbase">
<!-- 进度条-->
<div v-show="progressVisible" class="progress-container">
<div class="progress-bar"></div>
</div>
<a-upload
v-if="!uploadType"
:beforeUpload="beforeImageUpload"
list-type="picture-card"
:file-list="imageList"
:multiple="multiple"
:disabled="disabled"
@change="handleImageChange"
@preview="handlePreview"
:custom-request="customRequest"
>
<div v-if="imageList.length < limitNum && !disabled">
<a-icon type="plus" />
<div class="ant-upload-text">上传</div>
</div>
</a-upload>
<a-upload
v-else
name="file"
:file-list="imageList"
:beforeUpload="beforeImageUpload"
:multiple="multiple"
:disabled="disabled"
:custom-request="customRequest"
@change="handleImageChange"
>
<!-- list-type="picture" -->
<div v-if="imageList.length < limitNum && !disabled">
<a-button> <a-icon type="upload" /> 上传 </a-button>
</div>
</a-upload>
<!-- 图片预览 -->
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</template>
<script>
import UploadImage, DeleteImage from '@/api/public'
function getBase64(file)
return new Promise((resolve, reject) =>
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => resolve(reader.result)
reader.onerror = (error) => reject(error)
)
function getName(url)
const list = url.split('/')
return list[list.length - 1].split('.')[0]
export default
name: 'UpBase64',
props:
defaultImageList:
type: Array,
default: function ()
return []
,
required: true,
,
// 组件展示样式
uploadType:
type: Boolean,
default: false,
required: false,
,
// 文件类型列表
fileTypeList:
type: Array,
default: function ()
return []
,
required: false,
,
// 容量大小
limitSize:
type: Number,
default: 2,
required: false,
,
// 个数
limitNum:
type: Number,
default: 20,
required: false,
,
// 是否支持多选
multiple:
type: Boolean,
default: false,
required: false,
,
// 是否禁用
disabled:
type: Boolean,
default: false,
required: false,
,
dwidth:
type: Number,
default: 0,
require: false,
,
dheight:
type: Number,
default: 0,
require: false,
,
,
data()
return
previewVisible: false,
progressVisible: false,
progressValue: 10,
previewImage: '',
imageList: [],
,
watch:
defaultImageList(newVal)
this.imageList = this.handleData(newVal)
,
,
created()
this.imageList = this.handleData(this.defaultImageList)
,
methods:
// ---------------------------------------------img--start
// 上传格式限制
beforeImageUpload(file)
return new Promise((resolve, reject) =>
if (this.fileTypeList.length != 0)
const index = this.fileTypeList.indexOf(file.type)
if (index <= -1)
this.$message.error(`您只能上传$this.fileTypeList文件`)
return reject(new Error(`您只能上传$this.fileTypeList文件,不能传$file.type文件`))
const limitSize = file.size / 1024 / 1024 < this.limitSize
if (!limitSize)
this.$message.error(`文件大小不能大于$this.limitSizeMB`)
return reject(new Error(`文件大小不能大于$this.limitSizeMB`))
const checkSize = this.checkImageWH(file, this.dwidth, this.dheight)
return Promise.resolve(checkSize)
.then(() => resolve())
.catch((e) =>
reject(e)
)
)
,
checkImageWH(file, width, height)
// 参数分别是上传的file,想要限制的宽,想要限制的高
const that = this
return new Promise(function (resolve, reject)
let filereader = new FileReader()
filereader.onload = (e) =>
let src = e.target.result
const image = new Image()
image.onload = function ()
if ((width && this.width !== width) || (height && this.height !== height))
// 上传图片的宽高与传递过来的限制宽高作比较,超过限制则调用失败回调
const message = `图片宽高不满足,需要:宽 $width || '不限制',高 $height || '不限制'\\n,当前图片宽:$
this.width
,高:$this.height`
that.$message.error(message)
reject(new Error(message))
else
resolve( width: this.width, height: this.height )
image.onerror = reject
image.src = src
filereader.readAsDataURL(file)
)
,
async handlePreview(file)
if (!file.url && !file.preview)
file.preview = await getBase64(file.originFileObj)
this.previewImage = file.url || file.preview
this.previewVisible = true
,
handleCancel()
this.previewVisible = false
,
// 自定义上传逻辑
customRequest( action, file, onSuccess, onError, onProgress )
this.progressVisible = true
new Promise((resolve) =>
const fileReader = new FileReader()
// 转化为base64
fileReader.readAsDataURL(file)
fileReader.onload = async () =>
let index =
uid: this.genId(5),
name: file.name,
status: 'done',
url: fileReader.result,
let params =
name: index.uid,
data: index.url,
try
let res = await UploadImage(params)
index.url = res.result.url
if (res.status == 1)
setTimeout(() =>
this.imageList = [...this.imageList.filter((item) => item.status === 'done'), index]
this.$message.success('文件上传成功!')
this.progressVisible = false
this.handleChange()
resolve(fileReader.result)
, 2000)
else
this.imageList = [...this.imageList.filter((item) => item.status === 'done')]
this.$message.success(res.msg)
this.handleChange()
resolve(fileReader.result)
catch (error)
console.log('upimg:', error)
finally
)
,
// 处理事件
async handleImageChange(info)
try
// 删除图片
let res = await DeleteImage(getName(info.file.url))
console.log(res, 89)
if (res.status == 1)
this.$message.success('删除成功!')
else
this.$message.error('删除失败!')
catch (error)
// console.log('delimg:', error)
finally
let fileList = [...info.fileList]
this.imageList = fileList
this.handleChange()
,
handleChange()
let index = this.imageList
.filter((item) => item.url)
.map((item) =>
return item.url
)
// if (index?.length <= 0) return
this.$emit('change', index ? index : [])
,
genId(length)
return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36)
,
handleData(list)
return list.map((item) =>
let index = this.genId(5)
return
uid: index,
name: index,
status: 'done',
url: item,
)
,
// ---------------------------------------------img--end
,
</script>
<style lang="less" scoped>
.ant-upload-select-picture-card i
font-size: 32px;
color: #999;
.ant-upload-select-picture-card .ant-upload-text
margin-top: 8px;
color: #666;
</style>
<style>
.progress-container
width: 100px;
height: 7px;
background-color: #ffffff;
border-radius: 5px;
.progress-bar
height: 100%;
border-radius: 5px;
animation-fill-mode: forwards;
animation-name: progressBar;
animation-iteration-count: infinite;
background-color: #44cef6;
animation-duration: 2s;
animation-iteration-count: 1;
@keyframes progressBar
0%
width: 0%;
100%
width: 100%;
</style>
使用
<template>
<page-header-wrapper>
<div class="khdztps">
<div class="container">
<div class="left">
<div class="wrap">
<div class="title">
<h2>客户端底图上传</h2>
</div>
<span class="tips">*上传格式为“.jpg 和.png“,大小不得超过1M,(375*665)</span>
<b-upload-image-base64
ref="bUploadImageBase641"
:limitNum="1"
@change="imageChange($event, 'inviteBgImageList')"
:defaultImageList="inviteBgImageList"
:dwidth="375"
:dheight="665"
/>
</div>
<div class="wrap">
<div class="title">
<h2>客户端ICON替换</h2>
</div>
<span class="tips">*上传格式只能为“.png”,大小不得超过300k,(24*24)x3</span>
<div class="icon">
<div class="wxz">
<span class="title">未选中</span>
<div class="imgBox">
<b-upload-image-base64
ref="bUploadImageBase642"
:limitNum="1"
@change="imageChange($event, 'inviteHomeImageList')"
:defaultImageList="inviteHomeImageList"
:dwidth="24 * 3"
:dheight="24 * 3"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<a-button type="primary" @click="saveSubmit">保存并预览</a-button>
</div>
</page-header-wrapper>
</template>
<script>
import commitCustomConfigure, queryCustomConfigure from '@/api/feedback'
import bUploadImageBase64 from '@/components/Plug/BUploadImageBase64.vue'
export default
name: 'Khdztps',
components:
bUploadImageBase64,
,
data()
return
inviteBgImageList: [],
inviteHomeImageList: [],
dataList:
BGUrl: '',
HomeUrl: '',
,
,
created() ,
mounted()
this.queryCustomConfigure()
,
methods:
saveSubmit()
this.commitCustomConfigure()
,
// 保存
async commitCustomConfigure()
try
let res = await commitCustomConfigure(this.dataList)
console.log(res, 89)
if (res.status == 1)
this.$message.success('设置成功!')
else
this.$message.error(res.msg)
catch (error)
console.log('sub:', error)
,
// 获取 - 数据回填
async queryCustomConfigure()
try
let res = await queryCustomConfigure()
console.log(res, 89)
if (res.status == 1)
// this.$message.success('成功!')
this.dataList = res.result
if (res.result.BGUrl)
this.inviteBgImageList.push(res.result.BGUrl)
if (res.result.HomeUrl)
this.inviteHomeImageList.push(res.result.HomeUrl)
else
this.$message.error(res.msg)
catch (error)
console.log('sub:', error)
,
// 图片上传成功赋值
imageChange(e, key)
console.log(e, key)
switch (key)
// 图片
case 'inviteBgImageList':
this.dataList.BGUrl = e[0] || ''
break
case 'inviteHomeImageList':
this.dataList.Unselect.Home = e[0] || ''
break
default:
break
,
,
destroyed() ,
activated() ,
deactivated() ,
</script>
以上是关于Vue中图片上传组件封装-antd的a-upload二次封装-案例的主要内容,如果未能解决你的问题,请参考以下文章
AntD框架的upload组件上传图片时使用customRequest方法自定义上传行为