封裝Vue Element的upload上傳組件


 

本來昨天就想分享封裝的這個upload組件,結果剛寫了兩句話,就被邊上的同事給偷窺上了

一直都很忙,寫分享基本都是在中午午休時趕出來的,然后趁着在工作中頸椎疼的難以忍受時稍微休息一下的過程中排版發出來的。不過我也發現一個現象,就是我分享的有關封裝的react方面的組件的關注度沒有封裝的vue方面的組件的關注度來得高,有可能是百度對我分享的vue方面的組件做了收錄,所以大家也能在百度上搜索到,而我分享的react方面的組件卻基本沒有被百度收錄的原因,或許也有可能是用vue的人多過用react的人,但我無意去對比兩者,大家開心就好。

今天寫的這個upload組件也是采用的函數式組件,然后結合着Element ui的上傳組件來封裝,接下來就看具體實現吧。

還是先來一張效果圖:

1、封裝的上傳組件Upload.js

import { Message } from 'element-ui' const 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:剛才發現我邊上那個同事在用挖耳勺掏耳朵的時候還在偷瞄的電腦屏幕,冊那!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM