vue上傳(相容IE9)
阿新 • • 發佈:2019-01-03
專案中vue檔案上傳功能原來使用的是element ui元件,頭像上傳裁剪使用的是vue-image-crop-upload,但是這兩個元件只支援到IE10+,現在專案要求相容IE9,這兩個元件就沒辦法實現。
我基於Web Uploader封裝了vue上傳功能,Web Uploader是一個簡單的以HTML5為主,FLASH為輔的上傳元件,IE10以下可以使用FLASH上傳。廢話不多說,直接上碼。
我將檔案放在components下:
其中index.vue為封裝的一層,Uploader.swf和webuploader.js可以在webupload官網下載
index.vue:
<template> <div class="_upload"> </div> </template> <script> import 'jquery'; import './webuploader'; import swgimg from './Uploader.swf'; export default { props: { // 上傳按鈕ID upload_button: { type: String, default: '._upload' }, // 上傳地址 cdnUrl: { type: String, default: '' }, // 上傳最大數量 預設為100 fileNumLimit: { type: Number, default: 100 }, // 大小限制 預設2M fileSingleSizeLimit: { type: Number, default: 2048000 }, //上傳token等引數 formData: { type: Object, default: null }, imageUrl: { type: String, default: '' }, accept: { type: Object, default: null }, keyGenerator: { type: Function, default: function (file) { const currentTime = new Date().getTime(); const key = currentTime + "." + file.name; return key; } } }, data() { return { }; }, mounted() { this.initWebUpload(); }, methods: { initWebUpload() { var self = this; var uploader = WebUploader.create({ auto: true, // 選完檔案後,是否自動上傳 swf: swgimg, // swf檔案路徑 server: self.cdnUrl, // 檔案接收服務端 pick: { id: self.upload_button, multiple:false, label: '' }, // 選擇檔案的按鈕。可選 // 允許選擇檔案格式。 accept: self.accept, thread: 1, fileNumLimit: self.fileNumLimit, //限制上傳個數 fileSingleSizeLimit: self.fileSingleSizeLimit, //限制單個上傳圖片的大小 formData: self.formData, //上傳七牛所需引數 duplicate: true //重複上傳 }); // 當有檔案被新增進佇列的時候,新增到頁面預覽 uploader.on( 'fileQueued', function( file ) { uploader.options.formData.key = self.keyGenerator(file); self.$emit('before', file); }); // 檔案上傳過程中建立進度條實時顯示。 uploader.on( 'uploadProgress', function( file, percentage ) { self.$emit('progress', file, percentage); }); uploader.on( 'uploadSuccess', function( file, response ) { self.$emit('success', file, response); }); uploader.on( 'error', function( type ) { let errorMessage = ''; if (type == "F_EXCEED_SIZE") { errorMessage = "檔案大小不能超過" + self.fileSingleSizeLimit/(1024*1000) + "M"; } else if (type == "Q_EXCEED_NUM_LIMIT") { errorMessage = '檔案上傳已達到最大上限數'; } else { errorMessage = "上傳出錯!請檢查後重新上傳!錯誤程式碼" + type; } self.$emit('error', errorMessage); }); uploader.on( 'uploadComplete', function( file, response ) { self.$emit('complete', file, response); }); }, } } </script> <style> .webuploader-container { position: relative; } .webuploader-element-invisible { position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px,1px,1px,1px); } .webuploader-pick { position: relative; display: inline-block; cursor: pointer; background: #00b7ee; padding: 10px 15px; color: #fff; text-align: center; border-radius: 3px; overflow: hidden; } .webuploader-pick-hover { background: #00a2d4; } .webuploader-pick-disable { opacity: 0.6; pointer-events:none; } </style>
這裡我說下我踩得幾個坑:
1. webuploader官網下載之後是存在css的,我使用
<style scoped>
@import "./webuploader.css";
</style>
但是未生效,我就將css樣式放入vue頁面中;2.使用webuploader必須先引進jquery,不然會報 jQuery or Zepto not found! 錯誤;
3.import swf檔案時,必須在webpack.conf.js中新增
不然會因為不識別這種格式報錯;{ //視訊載入 test: /\.(mp4|flv|swf)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader", options: { name: utils.assetsPath("video/[name].[hash:7].[ext]") }
4.我使用webuploader的版本為0.1.5,webuploader.js中
存在callee方法,如果在嚴格模式下,會報input.on( 'change', function( e ) { var fn = arguments.callee, clone; me.files = e.target.files; // reset input clone = this.cloneNode( true ); clone.value = null; this.parentNode.replaceChild( clone, this ); input.off(); input = $( clone ).on( 'change', fn ) .on( 'mouseenter mouseleave', mouseHandler ); owner.trigger('change'); }); label.on( 'mouseenter mouseleave', mouseHandler );
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
解決辦法為:修改該段程式碼 var changeFn = (function even(that, e){
var clone;
me.files = e.target.files;
// reset input
clone = that.cloneNode( true );
clone.value = null;
that.parentNode.replaceChild( clone, that );
input.off();
input = $(clone).on('change', function(e){
even(this, e);
}).on('mouseenter mouseleave', mouseHandler);
owner.trigger('change');
});
input.on('change', function(e){
changeFn(this, e);
});
label.on( 'mouseenter mouseleave', mouseHandler );
即可。下面是呼叫實現功能的一個demo頁面
demo.vue:
<template>
<div>
<web-upload :cdn-url="cdnUrl" :form-data="cdnParams" @before="beforeUpload" :accept="accept"
@progress="uploadProgress" @success="handleSuccess" :key-generator="keyGenerator"
@error="error" @complete="handleComplete" upload_button=".btns">
</web-upload>
<p>
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</p>
<div class="progressContainer" :style="{display: display}">
<div class="progress" :style="{width:progress+'%'}">
<b>{{progress}}%</b>
</div>
</div>
<div class="btns">
<div id="picker">選擇檔案</div>
</div>
</div>
</template>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #20a0ff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<script>
import WebUpload from 'components/webupload';
export default {
components: {
WebUpload
},
data() {
return {
display: "none",
progress: 0,
accept: null,
cdnUrl: '',
host: '',
imageUrl: '',
cdnParams: {
token: '',
key: '',
name: '',
chunk: 0,
chunks: 1
}
};
},
methods: {
handleSuccess(file, res) {
this.imageUrl = this.host.concat(res.key);
},
beforeUpload(file) {
},
uploadProgress(file, percentage) {
this.display = "block";
this.progress = percentage * 100;
},
error(message) {
this.$message.error(message);
},
handleComplete() {
this.display = "none";
},
keyGenerator(file) {
const currentTime = new Date().getTime();
this.cdnParams.key = "test/cdn/ie9/" + currentTime + "." + file.name;
return this.cdnParams.key;
}
}
}
</script>
我這是直接上傳到七牛CDN。
如有其他問題,可在評論留言
下面是呼叫API:
外掛已上傳NPM
注意:ie9使用的為flash,地址不支援https,所以伺服器地址使用http
r如有問題一的個簡單的以HTML5為主,FLASH為輔的現代檔案上傳元件一個簡單的以HTML5為主,FLASH為輔的現代檔案上傳元件一個簡單的以HTML5為主,FLASH為輔的現代檔案上傳元件一個簡單的以HTML5為主,FLASH為輔的現代檔案上傳元件