vue3 封装文件上传组件
生活随笔
收集整理的這篇文章主要介紹了
vue3 封装文件上传组件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
由于工作需要,項目中經常需要文件上傳這個功能,根據業務的需求,使用vue3 簡單封裝通用型組件。
作用:主要是用來上傳圖片的一個通用型組件,當然可以上傳文件。支持校驗 尺寸 , 像素, 文件大小,可以多文件上傳。
在下面貼上組件代碼:
<template><div class="upload-button"><template v-if="multiple"><inputref="input"type="file"multiple="multiple":accept="acceptType"@change="handleChange"/></template><template v-else><input ref="input" type="file" :accept="acceptType" @change="handleChange" /></template></div> </template><script> import { reactive, ref } from '@vue/composition-api'; import { Message } from 'element-ui'; import { post } from 'axios'; // 請求也是的,建議直接使用項目中已經封裝好的請求函數來調接口。我這是自己搭建的練手的項目,就沒去封裝請求。 import commonApi from '@/api/common'; // 這個是接口地址,根據自己需求改。 const defaultType = ['bmp','jpg','png','tif','gif','pcx','tga','exif','fpx','svg','psd','cdr','pcd','dxf','ufo','eps','ai','raw','WMF','webp', ]; export default {props: {multiple: {// 是否多選type: Boolean,default: false,},acceptType: {// 文件類型type: String,default: 'image/*',},type: {// 限制上傳文件類型type: String,default: undefined,},size: {// 限制上傳文件尺寸type: String,default: undefined,},bulk: {// 限制上傳文件大小type: Number,default: 0,},},setup(props, c) {const { bulk, type, size, multiple } = reactive(props);const uploading = ref(false);const input = ref(null);const url = ref(undefined);let uploadFiles = reactive([]);const inputClick = () => {if (uploading.value) {return Message.warning('請等待前面的文件完成上傳!');}return input.value.click();};const handleChange = ({ target }) => {if (multiple) uploadFiles = [...target.files];uploadFile(target.files[0]);target.value = '';};const uploadFile = async (file) => {try {if (type) await detectorType(file);if (bulk) await detectorBulk(file);if (size) await detectorSize(file);uploading.value = true;const fd = new FormData();url.value = commonApi.addUserEmoticon;fd.append('file', file); // 可以通過這種形式,來傳遞其他項目中要傳遞的參數。const data = await post(url.value, fd, {headers: {'content-type': 'multipart/form-data',},});c.emit('url', data); // 將請求到的數據 拋出去uploaded(false);} catch (err) {uploaded(err);}};const detectorType = (file) => {return new Promise((resolve, reject) => {const sizeList = type.split(',');const fileSize = file.name.split('.');const fileExtension = fileSize[fileSize.length - 1].toLowerCase();if (!sizeList.includes(fileExtension)) {if (!defaultType.includes(fileExtension)) {Message.error('文件類型不對!');} else {Message.error('圖片類型不對!');}reject(new Error());} else {resolve(true);}});};const detectorBulk = (file) => {return new Promise((resolve, reject) => {const fileSize = file.size / 1024 / 1024;if (fileSize > bulk) {Message.error(`大小超出${bulk}M`);reject(new Error());} else {resolve(true);}});};const detectorSize = (file) => {return new Promise((resolve, reject) => {const image = new Image();const URL = window.URL || window.webkitURL;image.onload = () => {const sizes = size.split(',');if (image.width === Number(sizes[0]) && image.height === Number(sizes[1])) {resolve(true);} else {Message.error({type: 'error',message: `請上傳尺寸為 ${sizes.join(' x ')} 的圖片`,});reject(new Error());}};image.src = URL.createObjectURL(file);});};const uploaded = (err, state = false) => {uploading.value = false;if (!err) {if (multiple && uploadFiles.length > 1) {uploadFiles = uploadFiles.slice(1, uploadFiles.length - 1);uploadFile(uploadFiles[0]);} else {Message.success('上傳成功!');}}};return {input,inputClick,handleChange,};}, }; </script><style scoped lang="less"></style>如何使用:
首先要修改組件里面的 接口api, 和請求方式函數。
下面是我寫的小demo,隨便寫寫,不是很嚴謹。
<template><div><div><span v-if="urlList"><imgv-for="(item, index) in urlList":key="item.url"class="img":src="item.url"fit="contain"style="margin-right: 10px"@click="getImg(index)"/></span><imgv-if="(!multiple && !urlList.length) || (multiple && urlList)"class="img":src="`${require('@/assets/notice/unselected.png')}`"fit="contain"@click="getImg"/></div><!-- <UploadButtonref="upload"style="display: none"type="jpg,jpeg,png"size="4087,2711":bulk="2":multiple="multiple"@inputpp="channelParameter"/> --><uploadref="upload"style="display: none"type="jpg,jpeg,png":bulk="bulk"size="4087,2710":multiple="multiple"@url="channelParameter"/><button @click="clickButton">點擊</button></div> </template><script> import { ref, reactive } from '@vue/composition-api'; // import UploadButton from './SingleButton.vue'; import upload from './upload'; // 直接引入這個組件 export default {components: {// UploadButton,upload,},setup() {const upload = ref(null);const multiple = ref(false);const urlList = reactive([]);const bulk = ref(2);const getImg = () => {console.log(upload.value, 'pppupload.value');upload.value.inputClick();};const channelParameter = (value) => {if (!value.data.data) return;console.log(value, 'ppp');if (multiple) {// if(index===0 || index){// urlList.splice(index,)// }urlList.push({ url: value.data.data.emoticonPath });} else {urlList.push({ url: value.data.data.emoticonPath });}console.log(urlList, 'urlList');};const clickButton = () => {bulk.value += 1;console.log(bulk.value, 'bulk.value');};return {// 變量upload,urlList,multiple,bulk,// 事件channelParameter,getImg,clickButton,};}, }; </script><style scoped lang="less"> .img {width: 80px;height: 80px;vertical-align: top;margin-left: 12px;border-radius: 4px; } </style>總結
以上是生活随笔為你收集整理的vue3 封装文件上传组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: element from表单个别sele
- 下一篇: 什么是白马股