分享项目中上传组件上传进度的用法,已经表单和表格中使用上传组件,以及如何全局封装上传组件,简化代码,可以复用配置化。
上传组件使用 vxe-upload,只需要配置好参数 upload-method 就可以自动上传,接收一个对, 包含 url、name、size 等属性。
上传附件基本用法
<template>
<div>
<vxe-upload v-model="fileList" multiple :upload-method="uploadMethod"></vxe-upload>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
const fileList = []
const uploadMethod = ({ file }) => {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: '' }
return {
...res.data
}
})
}
return {
fileList,
uploadMethod
}
}
}
</script>
上传图片基本用法
<template>
<div>
<vxe-upload v-model="imgList" mode="image" multiple :upload-method="uploadMethod"></vxe-upload>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
const imgList = []
const uploadMethod = ({ file, updateProgress }) => {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: '' }
return {
...res.data
}
})
}
return {
imgList,
uploadMethod
}
}
}
</script>
表单中使用
<template>
<div>
<vxe-form v-bind="formOptions"></vxe-form>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
const fileList1ItemRender = {
name: 'VxeUpload',
props: {
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const fileList2ItemRender = {
name: 'VxeUpload',
props: {
multiple: true,
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const imgList1ItemRender = {
name: 'VxeUpload',
props: {
mode: 'image',
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const imgList2ItemRender = {
name: 'VxeUpload',
props: {
mode: 'image',
multiple: true,
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const actionItemRender = {
name: 'VxeButtonGroup',
options: [
{ content: '重置', type: 'reset' },
{ content: '提交', type: 'submit', status: 'primary' }
]
}
const formOptions = {
titleWidth: 120,
data: {
name: 'test1',
nickname: 'Testing',
sex: '',
fileList1: [],
fileList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
],
imgList1: [],
imgList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
]
},
items: [
{ field: 'name', title: '名称', span: 24, itemRender: { name: 'VxeInput' } },
{ field: 'fileList1', title: '上传附件', span: 24, itemRender: fileList1ItemRender },
{ field: 'fileList2', title: '上传附件多选', span: 24, itemRender: fileList2ItemRender },
{ field: 'imgList1', title: '上传图片', span: 24, itemRender: imgList1ItemRender },
{ field: 'imgList2', title: '上传图片多选', span: 24, itemRender: imgList2ItemRender },
{ align: 'center', span: 24, itemRender: actionItemRender }
]
}
return {
formOptions,
fileList1ItemRender,
fileList2ItemRender,
imgList1ItemRender,
imgList2ItemRender
}
}
}
</script>
表格中使用
<template>
<div>
<vxe-grid v-bind="gridOptions"></vxe-grid>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
const fileList1CellRender = {
name: 'VxeUpload',
props: {
readonly: true,
progressText: '{percent}%',
moreConfig: {
maxCount: 1,
layout: 'horizontal'
},
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const fileList2CellRender = {
name: 'VxeUpload',
props: {
multiple: true,
showButtonText: false,
progressText: '{percent}%',
moreConfig: {
maxCount: 1,
layout: 'horizontal'
},
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const imgList1CellRender = {
name: 'VxeUpload',
props: {
mode: 'image',
readonly: true,
progressText: '{percent}%',
moreConfig: {
maxCount: 1
},
imageStyle: {
width: 40,
height: 40
},
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const imgList2CellRender = {
name: 'VxeUpload',
props: {
mode: 'image',
multiple: true,
showButtonText: false,
progressText: '{percent}%',
moreConfig: {
maxCount: 1
},
imageStyle: {
width: 40,
height: 40
},
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
}
const gridOptions = {
border: true,
showOverflow: true,
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', title: 'Name', minWidth: 180 },
{ field: 'fileList1', title: '附件列表', width: 240, cellRender: fileList1CellRender },
{ field: 'fileList2', title: '上传附件', width: 300, cellRender: fileList2CellRender },
{ field: 'imgList1', title: '图片列表', width: 160, cellRender: imgList1CellRender },
{ field: 'imgList2', title: '上传图片', width: 210, cellRender: imgList2CellRender }
],
data: [
{
id: 10001,
name: 'Test1',
imgList1: [],
imgList2: [],
fileList1: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
],
fileList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
]
},
{
id: 10002,
name: 'Test2',
imgList1: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' }
],
imgList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' }
],
fileList1: [],
fileList2: []
},
{
id: 10003,
name: 'Test3',
imgList1: [
{ name: 'fj577.jpg', url: 'https://vxeui.com/resource/img/fj577.jpg' }
],
imgList2: [
{ name: 'fj577.jpg', url: 'https://vxeui.com/resource/img/fj577.jpg' }
],
fileList1: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' },
{ name: 'fj187.jpg', url: 'https://vxeui.com/resource/img/fj187.jpg' }
],
fileList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' },
{ name: 'fj187.jpg', url: 'https://vxeui.com/resource/img/fj187.jpg' }
]
}
]
}
return {
gridOptions,
fileList1CellRender,
fileList2CellRender,
imgList1CellRender,
imgList2CellRender
}
}
}
</script>
全局封装,统一接口,配置化,高复用性
以上的使用有没有发现一个问题,就是上传组件都要写上传接口,那么有没有办法统一在一个地方写上传接口呢,答案是有的,非常简单,有几种方法:
- 第一种:将 vxe-upload 封装成自己的业务组件,直接使用业务组件就可以了。
- 第二种:使用全局默认参数配置上传、删除、下载的等接口**(推荐,最简单且最好用的方式)**
- 第三种:使用渲染器定义一个控件,将复用逻辑封装里面
接下来说的就是全局默认参数的用法:
import { VxeUI } from 'vxe-pc-ui'
import axios from 'axios'
VxeUI.setConfig({
upload: {
uploadMethod ({ file }) {
const formData = new FormData()
formData.append('file', file)
return axios.post('/api/pub/upload/single', formData).then((res) => {
// { url: ''}
return {
...res.data
}
})
}
}
})
表格使用
<template>
<div>
<vxe-grid v-bind="gridOptions"></vxe-grid>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
const fileList1CellRender = {
name: 'VxeUpload',
props: {
readonly: true,
progressText: '{percent}%',
moreConfig: {
maxCount: 1,
layout: 'horizontal'
}
}
}
const fileList2CellRender = {
name: 'VxeUpload',
props: {
multiple: true,
showButtonText: false,
progressText: '{percent}%',
moreConfig: {
maxCount: 1,
layout: 'horizontal'
}
}
}
const imgList1CellRender = {
name: 'VxeUpload',
props: {
mode: 'image',
readonly: true,
progressText: '{percent}%',
moreConfig: {
maxCount: 1
},
imageStyle: {
width: 40,
height: 40
}
}
}
const imgList2CellRender = {
name: 'VxeUpload',
props: {
mode: 'image',
multiple: true,
showButtonText: false,
progressText: '{percent}%',
moreConfig: {
maxCount: 1
},
imageStyle: {
width: 40,
height: 40
}
}
}
const gridOptions = {
border: true,
showOverflow: true,
columns: [
{ type: 'seq', width: 70 },
{ field: 'name', title: 'Name', minWidth: 180 },
{ field: 'fileList1', title: '附件列表', width: 240, cellRender: fileList1CellRender },
{ field: 'fileList2', title: '上传附件', width: 300, cellRender: fileList2CellRender },
{ field: 'imgList1', title: '图片列表', width: 160, cellRender: imgList1CellRender },
{ field: 'imgList2', title: '上传图片', width: 210, cellRender: imgList2CellRender }
],
data: [
{
id: 10001,
name: 'Test1',
imgList1: [],
imgList2: [],
fileList1: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
],
fileList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
]
},
{
id: 10002,
name: 'Test2',
imgList1: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' }
],
imgList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' }
],
fileList1: [],
fileList2: []
},
{
id: 10003,
name: 'Test3',
imgList1: [
{ name: 'fj577.jpg', url: 'https://vxeui.com/resource/img/fj577.jpg' }
],
imgList2: [
{ name: 'fj577.jpg', url: 'https://vxeui.com/resource/img/fj577.jpg' }
],
fileList1: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' },
{ name: 'fj187.jpg', url: 'https://vxeui.com/resource/img/fj187.jpg' }
],
fileList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' },
{ name: 'fj573.jpeg', url: 'https://vxeui.com/resource/img/fj573.jpeg' },
{ name: 'fj187.jpg', url: 'https://vxeui.com/resource/img/fj187.jpg' }
]
}
]
}
return {
gridOptions,
fileList1CellRender,
fileList2CellRender,
imgList1CellRender,
imgList2CellRender
}
}
}
</script>
表单使用
<template>
<div>
<vxe-form v-bind="formOptions"></vxe-form>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
const fileList1ItemRender = {
name: 'VxeUpload'
}
const fileList2ItemRender = {
name: 'VxeUpload',
props: {
multiple: true
}
}
const imgList1ItemRender = {
name: 'VxeUpload',
props: {
mode: 'image'
}
}
const imgList2ItemRender = {
name: 'VxeUpload',
props: {
mode: 'image',
multiple: true
}
}
const actionItemRender = {
name: 'VxeButtonGroup',
options: [
{ content: '重置', type: 'reset' },
{ content: '提交', type: 'submit', status: 'primary' }
]
}
const formOptions = {
titleWidth: 120,
data: {
name: 'test1',
nickname: 'Testing',
sex: '',
fileList1: [],
fileList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
],
imgList1: [],
imgList2: [
{ name: 'fj562.png', url: 'https://vxeui.com/resource/img/fj562.png' }
]
},
items: [
{ field: 'name', title: '名称', span: 24, itemRender: { name: 'VxeInput' } },
{ field: 'fileList1', title: '上传附件', span: 24, itemRender: fileList1ItemRender },
{ field: 'fileList2', title: '上传附件多选', span: 24, itemRender: fileList2ItemRender },
{ field: 'imgList1', title: '上传图片', span: 24, itemRender: imgList1ItemRender },
{ field: 'imgList2', title: '上传图片多选', span: 24, itemRender: imgList2ItemRender },
{ align: 'center', span: 24, itemRender: actionItemRender }
]
}
return {
formOptions,
fileList1ItemRender,
fileList2ItemRender,
imgList1ItemRender,
imgList2ItemRender
}
}
}
</script>
现在是不发现上传件方式统一了,上传接口统一了,代码复用了,配置简单了,没有最强,只有更强!!!
github https://github.com/x-extends/vxe-pc-ui
gitee https://gitee.com/x-extends/vxe-pc-ui