本来昨天就想分享封装的这个upload组件,结果刚写了两句话,就被边上的同事给偷窥上了,于是在我全神贯注地写分享的时候他就神不知鬼不觉地突然移动到我身边,腆着脸问我在干啥呢。卧槽你妈,当场就把我吓了一跳,我说我没干嘛,在工作啊,然后我就把浏览器窗口切换了,他就来了一句:我看到了博客。我没搭理他,但心里就不停地在骂“槽你妈”,我确实很生气。其实我一直很反感那种坐在你边上有事没事就斜眼瞄你的电脑屏幕的同事,那种上班期间被偷窥的感觉很不爽。我这么说不是我特意去注意旁边的同事有没有在斜眼偷瞄我的电脑屏幕,因为我忙起来,我TM连我边上有没有人都不会有感觉的,之所以会经常发现被旁边的同事偷瞄,是因为工作时间久了,我的颈椎会很疼,头也疼,腰也很难受,所以我就会抬头仰望天花板或“葛优躺”靠在椅背上,这时我的眼睛余光就能很明确地感觉到我的电脑屏幕正在被旁边的同事偷瞄,我又不是那种直接回望过去:你TM的偷瞄什么呢?卧槽TM的,我就一直很奇怪,为什么我会经常跟那种喜欢偷瞄别人工作的人坐在一起,我也一直很奇怪,那种喜欢偷瞄别人工作或偷瞄别人电脑屏幕的人都是什么心理。但凡我发现我的电脑屏幕或我正在工作时被别人偷瞄,我就很不爽,浑身不自在,不知道大家有没有碰到这样的同事。

一直都很忙,写分享基本都是在中午午休时赶出来的,然后趁着在工作中颈椎疼的难以忍受时稍微休息一下的过程中排版发出来的。不过我也发现一个现象,就是我分享的有关封装的react方面的组件的关注度没有封装的vue方面的组件的关注度来得高,有可能是百度对我分享的vue方面的组件做了收录,所以大家也能在百度上搜索到,而我分享的react方面的组件却基本没有被百度收录的原因,或许也有可能是用vue的人多过用react的人,但我无意去对比两者,大家开心就好。

今天写的这个upload组件也是采用的函数式组件,然后结合着Element ui的上传组件来封装,接下来就看具体实现吧。

还是先来一张效果图:

1、封装的上传组件Upload.js

import { Message } from 'element-ui'
let OSS = require("ali-oss"); const SUFFIX = /.+(\.\w+)$/,
TIMEOUT = 60000,
BYTE = 1024,
RETRY_COUNT_MAX = 3,
ACCEPT = {
zip: 'application/zip,application/x-zip,application/x-zip-compressed',
pdf: 'application/pdf',
excel: 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
image: 'image/jpeg,image/bmp,image/png,image/gif',
},
getAccepts = accept => (Array.isArray(accept) ? accept : [accept]).map(ac => ACCEPT[ac]).join(','),
beforeCheck = (config, file) => {
let {max = Number.MAX_VALUE, accept = []} = config || {}, { size, type } = file, accepts = getAccepts(accept).split(','); //大小限制(M)
if(Math.pow(BYTE, 2) * max < size){
Message.warning(`文件不能超过${max}M`);
return false;
}
}; export default {
functional: true,
props: {config: Object, limit: Number, percentage: Function},
render: (h, ctx) => {
let {props, data: attrs, parent: {$store: { dispatch}}, children} = ctx, { config, limit } = props, retryCount = 0, { accept } = config;
if(!attrs.attrs.accept && accept){
attrs.attrs.accept = getAccepts(accept);
} Object.assign(props, {
action: '',
beforeUpload: file => beforeCheck(config, file),
onExceed: () => Message.warning(`最多可以上传${limit}个文件`),
httpRequest: opts => {
let { file, onError, onProgress, onSuccess } = opts, { uid, name, type } = file;
name = `${uid}${name.replace(SUFFIX, '$1')}`;
if(getAccepts(accept).indexOf(type) > -1) file.isImg = true dispatch('getClient').then(res => {
let aliClient = new OSS(res), { path } = res, url = path + '/' + name;
//multipartUpload是阿里云的分片(分段)大文件上传方法,这里也可以用put方法来上传单个小文件(aliClient.put)
aliClient.multipartUpload(url, file, {
timeout: TIMEOUT,
partSize: 500 * BYTE,
progress: p => {
onProgress(p * 100, file)
}
}).then(r => {
let { res: { requestUrls } } = r;
requestUrls = requestUrls.length < 1 ? '' : requestUrls[0]
if (requestUrls.indexOf('?') > -1) requestUrls = requestUrls.split('?')[0]
onSuccess({ res: file, url: requestUrls });
}).catch(err => {
let { name } = err;
if (aliClient.isCancel()) {
console.log('stop-upload!');
} else {
Message.error(err);
onError(err);
if (name.toLowerCase().indexOf('connectiontimeout') !== -1) {
if (retryCount < RETRY_COUNT_MAX) {
retryCount++;
props.httpRequest(opt)
}
}
}
});;
})
}
})
return h('el-upload', {props, ...attrs}, children)
}
}

本次封装的upload上传组件的封装方式和实现的功能与之前我所分享的封装React AntD的upload上传组件类似,你可以移步到那篇文章去详细了解,这里不再赘述。

另外,我们公司所上传的文件都是上传到了阿里云,所以这里顺带着将上传到阿里云的方法也给粗略地实现了。上传到阿里云所用到的API请自行查阅,本次分享也不再赘述。

2、使用方法:

<template>
<div class="container">
<p>第一种上传形式:</p>
<Upload :limit="limit" :on-success="onSuccess" :config="config" :on-progress="onProgress" :on-preview="onPreview" :on-remove="onRemove" list-type="picture-card">
<i class="el-icon-plus"></i>
</Upload>
<br />
<p>第二种上传形式:</p>
<Upload :limit="limit" :on-success="onSuccess" :config="config" :on-progress="onProgress" :on-preview="onPreview" :on-remove="onRemove">
<el-button size="small" type="primary">点击上传</el-button>
</Upload>
</div>
</template> <script>
import Upload from '@/components/Upload' export default {
components: {
Upload,
},
data() {
return {
limit: 1,
config: {
accept: "image", //接受上传的文件类型:zip、pdf、excel、image,也可以是文件类型所组成的数组类型如:['image', 'pdf'],则只可以上传图片或pdf类型的文件,也可以为空,则任何类型的文件都可以上传
max: 100, //文件大小
},
fileList: [],
}
},
methods: {
//文件上传完成后的回调
onSuccess({res: {uid, isImg}, url}) {
this.fileList.push({uid, url})
},
//文件上传进度条
onProgress(percent, file){ },
//上传文件
onRemove(file){
this.fileList = this.fileList.filter(n => n.uid != file.uid)
},
},
}
</script>

以前去面试的时候,经常会有面试官问我在开发的过程中有没有自己封装过组件,我说封装过,然后面试官就让我举例,那时候我的回答一般都不是基于函数式的封装,都还是带有状态和生命周期函数的那种封装,但面试官也没说啥。后来接触到函数式组件,才觉得这玩意儿是真好使。

PS:刚才发现我边上那个同事在用挖耳勺掏耳朵的时候还在偷瞄的电脑屏幕,册那!

封装Vue Element的upload上传组件的更多相关文章

  1. 封装react antd的upload上传组件

    上传文件也是我们在实际开发中常遇到的功能,比如上传产品图片以供更好地宣传我们的产品,上传excel文档以便于更好地展示更多的产品信息,上传zip文件以便于更好地收集一些资料信息等等.至于为何要把上传组 ...

  2. 使用Element的upload上传组件,不使用action属性上传

    1.需要实现的效果如下图,在点击提交的时候再提交file数据,和其他数据统一上传,我把file转换成了base64的格式,可以再上传之前显示缩略图 2.代码分析 action属性值为"#&q ...

  3. element-ui upload上传组件问题记录

    element-ui upload上传组件遇到的问题

  4. vue+element ui 的上传文件使用组件

    前言:工作中用到 vue+element ui 的前端框架,使用到上传文件,则想着封装为组件,达到复用,可扩展.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9 ...

  5. element-ui Upload 上传组件源码分析整理笔记(十四)

    简单写了部分注释,upload-dragger.vue(拖拽上传时显示此组件).upload-list.vue(已上传文件列表)源码暂未添加多少注释,等有空再补充,先记下来... index.vue ...

  6. 封装Vue Element的form表单组件

    前两天封装了一个基于vue和Element的table表格组件,阅读的人还是很多的,看来大家都是很认同组件化.高复用这种开发模式的,毕竟开发效率高,代码优雅,逼格高嘛.虽然这两天我的心情很糟糕,就像& ...

  7. 从0开始做一个的Vue图片/ 文件选择(上传)组件[基础向]

    原文:http://blog.csdn.net/sinat_17775997/article/details/58585142 之前用Vue做了一个基础的组件 vue-img-inputer ,下面就 ...

  8. 页面中使用多个element-ui upload上传组件时绑定对应元素

    elemet-ui里提供的upload文件上传组件,功能很强大,能满足单独使用的需求,但是有时候会存在多次复用上传组件的需求,如下图的样子,这时候就出现了问题,页面上有多个上传组件时,要怎么操作呢? ...

  9. 在vue项目中使用element-ui的Upload上传组件

    <el-upload v-else class='ensure ensureButt' :action="importFileUrl" :data="upLoadD ...

随机推荐

  1. Radiobutton基础语法

    .Radiobutton(root 主窗口,text 文本内容,value 值(可以通过set 和 get 获取到的值),variable 变量修改原来的StringVar) self.radio_m ...

  2. PHP 中的字符串变量

    PHP 字符串变量 字符串变量用于存储并处理文本. PHP 中的字符串变量 字符串变量用于包含有字符的值. 在创建字符串之后,我们就可以对它进行操作了.您可以直接在函数中使用字符串,或者把它存储在变量 ...

  3. Python os.tmpfile() 方法

    概述 os.tmpfile() 方法用于返回一个打开的模式为(w+b)的临时文件对象,这文件对象没有文件夹入口,没有文件描述符,将会自动删除.高佣联盟 www.cgewang.com 语法 tmpfi ...

  4. Python os.rmdir() 方法

    概述 os.rmdir() 方法用于删除指定路径的目录.仅当这文件夹是空的才可以, 否则, 抛出OSError.高佣联盟 www.cgewang.com 语法 rmdir()方法语法格式如下: os. ...

  5. Python os.lchmod() 方法

    概述 os.lchmod() 方法用于修改连接文件权限.高佣联盟 www.cgewang.com 只支持在 Unix 下使用. 语法 lchmod()方法语法格式如下: os.lchmod(path, ...

  6. day20:正则表达式

    单个字符的匹配 findall(正则表达式,字符串) 把符合正则表达式的字符串存在列表中返回 预定义字符集(8) \d 匹配数字 \D 匹配非数字 \w 匹配数字字母下划线 \W 匹配非数字或字母或下 ...

  7. 新老版本vue-cli的安装及创建项目等方式的比较

    vue-cli 3.0 正式版于2018年8月发布,截至到2020年08月05日版本已经更新到4.4.6.Vue CLI 的包名称由 vue-cli 改成了 @vue/cli,目前网上很多的Vue项目 ...

  8. Python-关于正则表达式的总结

    什么是正则表达式? 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),用于字符串的 匹配 和 提取 等操作.正则表达式在所有编程语言中都是通用的. 很多人 ...

  9. [问题记录] webpack devServer HtmlWebpackPlugin 没有加载 js、css

    webpack devServer 没有加载 js.css HtmlWebpackPlugin runtimeChunks 注入问题. 描述 写了一个极其简单的多页面 demo 启动开发服务器,发现样 ...

  10. Spring的第一个程序

    目录 一.Spring概述 1. Spring是什么? 2. IOC控制反转 二.Spring的第一个程序 1. 创建Maven项目 2. 加入maven依赖pom.xml 3. 定义接口和实体类 4 ...