1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > ant Design Vue2.0+vite+vue3+typescript+node后台项目实现使用upload一个表单上传多个图片

ant Design Vue2.0+vite+vue3+typescript+node后台项目实现使用upload一个表单上传多个图片

时间:2020-12-09 08:42:25

相关推荐

ant Design Vue2.0+vite+vue3+typescript+node后台项目实现使用upload一个表单上传多个图片

项目介绍

项目是模仿王者荣耀mobile端的后台admin管理项目,前端使用ant Design Vue2.0+vite+vue3+typescript来做,后端是node。

需求

添加英雄技能界面截图。

一开始使用ant design vue的upload的change来做,后来发现我这个界面的upload是需要循环遍历出来的,而change函数里面只有三个参数,无法获取每个upload的特定参数,挣扎了好久看官方文档,终于发现了customRequest这个参数,官方说明是【通过覆盖默认的上传行为,可以自定义自己的上传实现】,然并卵,官方并没有给出例子,查了半天,别人写的全都是vue2.x,没法只能自己看着2.x版本的来修改,奋斗了一天多,终于搞出了个基础版本,在此贴出一些核心实现代码,仅供各位大佬参考,还请各位大佬多多提供优化方案。

HeroEdit.vue代码

代码太多就贴出技能这块的好了,说明一下,点击添加技能按钮就会新建一个空的技能进formState.skills数组里面,然后循环遍历这个数组生成每个技能customRequest(options:any)里面的options对象中有data,可以通过:data="{index}"来携带参数,这个我们就知道每个upload对应的哪一个技能。

<a-tab-pane key="2" tab="技能"><a-button type="primary" @click="formState.skills.push({})"><template #icon><PlusOutlined /></template>添加技能</a-button><a-row type="flex"><a-col:span="10":offset="2"v-for="(item, index) of formState.skills":key="index"><a-form-item label="名称"><a-inputv-model:value="item.name"placeholder="请输入技能名称"></a-input></a-form-item><!-- :customRequest="customRequest" --><a-form-item label="图标" name="icon"><a-uploadv-model:avatar="item.icon"name="avatar":data="{ index }"list-type="picture-card"class="avatar-uploader":show-upload-list="false"action="/admin/api/upload":before-upload="beforeUpload":customRequest="customRequest"><imgv-if="formState.skills[index].icon":src="formState.skills[index].icon"alt="avatar"/><div v-else><loading-outlined v-if="loading"></loading-outlined><plus-outlined v-else></plus-outlined><div class="ant-upload-text">Upload</div></div></a-upload></a-form-item><a-form-item label="描述"><a-textareav-model:value="item.description"placeholder="请输入技能描述":rows="4"/></a-form-item></a-col></a-row></a-tab-pane>import {message } from 'ant-design-vue'import {PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'import {ValidateErrorEntity } from 'ant-design-vue/es/form/interface'import {defineComponent,onMounted,reactive,ref,toRaw,UnwrapRef,} from 'vue'import {useRouter, useRoute } from 'vue-router'import {reqAdd,reqGetDetail,reqGetList,reqUpdate,uploadImage,} from '../../api'interface FormState {name: stringavatar: string | undefinedtitle: stringcategories: string[]scores: objectitems1: string[]items2: string[]usageTips: stringbattleTips: stringteamTips: stringskills: any[]}function getBase64(img: any, callback: (base64Url: string) => void) {const reader = new FileReader()reader.addEventListener('load', () => callback(reader.result as string))reader.readAsDataURL(img)}export default defineComponent({setup() {const formState: UnwrapRef<FormState> = reactive({name: '',avatar: undefined,title: '',categories: [],scores: {},items1: [],items2: [],usageTips: '',battleTips: '',teamTips: '',skills: [],})/**自定义上传图片 */const customRequest = async (options: any) => {// console.log('customRequest', options)const {filename, file, action, data, onSuccess } = options// 定义上传的文件const formData = new FormData()formData.append(filename, file)// 发送请求const result: any = await uploadImage(action, formData)// console.log(result)getBase64(file, (base64Url: string) => {formState.skills[data.index].icon = base64Url})// 调用 onSuccess 不然会一直显示loadningonSuccess()}const beforeUpload = (file: FileItem) => {// console.log('beforeUpload')const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'if (!isJpgOrPng) {message.error('You can only upload JPG file!')}const isLt2M = file.size / 1024 / 1024 < 2if (!isLt2M) {message.error('Image must smaller than 2MB!')}return isJpgOrPng && isLt2M}return {customRequest,beforeUpload,formState,customRequest}}})<style>.avatar-uploader > .ant-upload {width: 128px;height: 128px;}.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>

index.ts请求的代码

import ajax from "./ajax";/**自定义图片上传接口 */export const uploadImage = (url: string, data: object) => ajax(url, data, 'POST')

服务端接收请求的代码

const express = require('express')const multer = require('multer')const upload = multer({dest: __dirname + '/../../public/uploads' })const routerFile = express.Router()// 上传图片routerFile.post('/upload', upload.single('avatar'), async (req, res) => {console.log('上传图片成功')const file = req.filefile.url = `http://localhost:8000/public/uploads/${file.filename}`res.send(file)})module.exports = routerFile

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。