由于工作需要,项目中经常需要文件上传这个功能,根据业务的需求,使用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, 和请求方式函数。

  1. 直接引入这个组件
  2. 给一个点击事件,upload.value.inputClick(); 触发组件里面的函数
  3. 然后监听 组件抛出的 emit 事件,会传递出来url

下面是我写的小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 封装文件上传组件相关推荐

  1. Vue:利用Plupload插件封装文件上传组件

    接上回<Plupload插件>,已经尝试将Plupload插件引入到HTML页面中,并进行参数配置,然后联合后端接口进行调试,完成了文件上传的工作.但是在Vue项目的开发中,我们更想将它封 ...

  2. vue 文件上传组件封装

    增加图片缩略图以及Word.txt文档在线预览 文件上传组件完整代码 <template><div><el-uploadclass="upload-demo&q ...

  3. Java 文件上传组件 Apache Commons FileUpload 应用指南(二)——FileUpload如何工作?

    在最初的 http 协议中,没有上传文件方面的功能.RFC1867("Form-based File Upload in HTML".) 为 http 协议添加了这个功能.客户端的 ...

  4. 使用 Apache的文件上传组件(common-fileupload)来实现文件的上传

    文章目录 一.前言/先导 二.步骤 三.源码 四.测试结果 五.文件的下载 一.前言/先导 maven的依赖: 注意:common-fileupload,它需要依赖于 commons-io组件: &l ...

  5. 1.6 文件上传组件

    1.6 文件上传组件 1.6.1 基本形制 <input type="file" name="myfile"/> form的完整形制如下,它必须设定 ...

  6. Bootstrap fileinput.js,最好用的文件上传组件

    本篇介绍如何使用bootstrap fileinput.js(最好用的文件上传组件)来进行图片的展示,上传,包括springMVC后端文件保存. 一.demo   二.插件引入 <link ty ...

  7. fileinput 时间_JavaScript_Bootstrap Fileinput文件上传组件用法详解,最近时间空余,总结了一些关...

    最近时间空余,总结了一些关于bootstrap fileinput组件的一些常见用法,特此分享到phpstudy平台,供大家参考,同时也方便以后的查找.本文写的不好还请见谅. 一.效果展示 1.原始的 ...

  8. ASP中文件上传组件ASPUpload介绍和使用方法

    [导读]要实现该功能,就要利用一些特制的文件上传组件.文件上传组件网页非常多,这里介绍国际上非常有名的ASPUpload组件 1 下载和安装ASPUpload   要实现该功能,就要利用一些特制的文件 ...

  9. 关于element-ui的upload文件上传组件的使用技巧总结

    关于element-ui的upload文件上传组件的技巧总结 简单说几点: uploader组件使用中的几个常见问题和解答 upload文件类型.大小的筛选: 多文件上传的配置: 3.文件列表的相关操 ...

最新文章

  1. 成熟的男人思考的东西
  2. php中jquery ajax请求参数,浅谈Jquery中Ajax异步请求中的async参数的作用
  3. CC2530, 各种智能家居通信技术比较
  4. Linux中一些常用的很巧妙的命令
  5. 【TensorFlow】TensorFlow从浅入深系列之六 -- 教你深入理解经典损失函数(交叉熵、均方误差)
  6. python爬虫获取下一页url_Python爬虫获取页面所有URL链接过程详解
  7. IO多路复用(select,poll,epoll)详解
  8. 利用R语言的Boruta包进行特征选择
  9. CentOS7.5搭建ELK6.2.4集群及插件安装
  10. SVM的对偶问题与核方法
  11. SCS【13】单细胞转录组之识别细胞对“基因集”的响应 (AUCell)
  12. 副业项目:今日头条音频项目,日入200+
  13. balsamiq mockups 3.0破解教程
  14. 测试架构需要具备哪些能力
  15. 入网许可证_进网许可证、电信设备入网许可证详解!
  16. Android 获取设备唯一标识
  17. 三大相关性分析之python
  18. 最好玩的计算机游戏排行,10款好玩的电脑单机游戏 好玩的单机游戏排行
  19. 股市风暴下的雪球架构改造经验分享
  20. 小米路由器获得BSI物联网安全风筝标志认证;IDC最新数据显示浪潮分布式存储增速中国第一 | 全球TMT...

热门文章

  1. python抓取网站的图片并下载到本地
  2. DEM挖填方分析--基于水平参考面计算
  3. python学习笔记(十一)标准库sys
  4. Gurobi 生产计划调度学习案例(含代码实现) (生产切换、装配计划)
  5. 使用Spring特性优雅书写业务代码
  6. Java多线程(十)之ReentrantReadWriteLock深入分析
  7. Django - ORM - 事务, 乐观锁, 悲观锁
  8. Java面试题—内部类和静态内部类的区别
  9. Linux环境搭建nginx负载
  10. 内核进程切换实现分析