From f28c9f6e980efd1f5dc7ad4aa9bf9ac270764def Mon Sep 17 00:00:00 2001 From: git Date: Fri, 20 May 2016 14:35:59 +0900 Subject: [PATCH] v0.1.0 --- .babelrc | 5 + README.md | 97 +++++++++ dist/build.js | 2 + dist/build.js.map | 1 + index.html | 78 +++++++ package.json | 50 +++++ src/fileUpload.vue | 508 +++++++++++++++++++++++++++++++++++++++++++++ src/main.js | 28 +++ webpack.config.js | 66 ++++++ 9 files changed, 835 insertions(+) create mode 100644 .babelrc create mode 100644 README.md create mode 100644 dist/build.js create mode 100644 dist/build.js.map create mode 100644 index.html create mode 100644 package.json create mode 100644 src/fileUpload.vue create mode 100644 src/main.js create mode 100644 webpack.config.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..41789ca --- /dev/null +++ b/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": ["es2015", "stage-2"], + "plugins": ["transform-runtime"], + "comments": false +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ead220 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +# vue-upload-component + +> Vue.js file upload component, Support for multiple file uploads, progress, html4, ie9 +**Html4 does not support the progress bar, file size, timeout, headers, response status code error of judgment** + + + +## Install + +``` bash + npm install vue-upload-component --save +``` + + +## Demo +``` html + +
+ +
+ + +``` + + + +## Build Setup + +``` bash +# install dependencies +npm install + +# serve with hot reload at localhost:8080 +npm run dev + +# build for production with minification +npm run build +``` + + +## Dispatch + addFileUpload + + removeFileUpload + + fileUploadProgress + + beforeFileUpload + + afterFileUpload + + + + +## Setting + +### Data +``` json + { + files: [{ + // + request: { + headers: { + "X-Csrf-Token": "xxxx", + }, + data: { + "_csrf_token": "xxxxxx", + }, + }, + }], + + // Global + request: { + headers: { + "X-Csrf-Token": "xxxx", + }, + data: { + "_csrf_token": "xxxxxx", + }, + }, + } +``` + + +### Props +``` html + +``` diff --git a/dist/build.js b/dist/build.js new file mode 100644 index 0000000..3a64f69 --- /dev/null +++ b/dist/build.js @@ -0,0 +1,2 @@ +!function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return e[i].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="/dist/",t(0)}([function(e,t,r){"use strict";var i=r(5);new Vue({el:"#app",components:{FileUpload:i},data:{accept:"image/*",size:10485760,multiple:!0},compiled:function(){this.$refs.upload.request={headers:{"X-Csrf-Token":"xxxx"},data:{_csrf_token:"xxxxxx"}}},methods:{remove:function(e){this.$refs.upload.files.$remove(e)}}})},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t["default"]={props:{title:{type:String,"default":"Upload file"},name:{type:String,required:!0},id:{type:String},action:{type:String,required:!0},accept:{type:String},multiple:{type:String},timeout:{type:Number},size:{type:Number}},components:{inputFile:{template:'',methods:{change:function(e){this.$parent._addFileUploads(e.target),this.$destroy()}}}},data:function(){return{files:[],active:!1,uploaded:!0,request:{data:{},headers:{}}}},init:function(){var e=document.createElement("input");e.type="file",window.FormData&&e.files?this.$mode="html5":this.$mode="html4",this._index=0,this._files={}},watch:{files:function(e){for(var t=[],r=0;r0&&e.size>=0&&e.size>this.size))return void("html5"==this.$mode?this._fileUploadHtml5(e):this._fileUploadHtml4(e));e.error="Size",e.errno="size"}}this.active=!1,this.uploaded=!0}},_fileUploadHtml5:function(e){var t=this,r=this._files[e.id],i=!1,n=new window.FormData;n.append(this.name,r.file);for(var o in this.request.data)n.append(o,this.request.data[o]);for(var o in e.request.data)n.append(o,e.request.data[o]);var s=new XMLHttpRequest;s.upload.onprogress=function(r){return e.removed?void s.abort():t.active&&e.active?(r.lengthComputable&&(e.progress=(r.loaded/r.total*100).toFixed(2)),void t.$dispatch("fileUploadProgress",e,t)):void s.abort()};var a=function(r){switch(r.type){case"timeout":e.errno="timeout",e.error="Timeout";break;case"abort":e.errno="abort",e.error="Abort";break;case"error":s.status?s.status>=500?(e.errno="server",e.error="Server"):s.status>=400&&(e.errno="denied",e.error="Denied"):(e.errno="network",e.error="Network");break;default:s.status>=500?(e.errno="server",e.error="Server"):s.status>=400?(e.errno="denied",e.error="Denied"):(e.progress="100.00",e.success=!0)}if(e.active=!1,s.responseText){var n=s.getResponseHeader("Content-Type");n&&-1!=n.indexOf("/json")?e.data=JSON.parse(s.responseText):e.data=s.responseText}i||(i=!0,e.removed||t.$dispatch("afterFileUpload",e,t),setTimeout(function(){t._fileUploads()},50))};s.onload=a,s.onerror=a,s.onabort=a,s.ontimeout=a,this.timeout&&(s.timeout=this.timeout),s.open("POST",this.action);for(var o in this.request.headers)s.setRequestHeader(o,this.request.headers[o]);for(var o in e.request.headers)s.setRequestHeader(o,e.request.headers[o]);s.send(n),e.active=!0,r.xhr=s;var l=setInterval(function(){t.active&&e.active&&!e.success&&!e.errno||(clearInterval(l),e.success||e.errno||s.abort())},50);this.$dispatch("beforeFileUpload",e,this)},_fileUploadHtml4:function(e){var t=this,r=this._files[e.id],i=!1,n=function(e){27==e.keyCode&&e.preventDefault()},o=document.createElement("iframe");o.id="upload-iframe-"+e.id,o.name="upload-iframe-"+e.id,o.src="about:blank",o.style.width="1px",o.style.height="1px",o.style.top="-9999px",o.style.left="-9999px",o.style.position="absolute",o.style.marginTop="-9999em";var s=document.createElement("form");s.action=this.action,s.name="upload-form-"+e.id,s.setAttribute("method","POST"),s.setAttribute("target","upload-iframe-"+e.id),s.setAttribute("enctype","multipart/form-data"),s.appendChild(r.el);for(var a in this.request.data){var l=document.createElement("input");l.type="hidden",l.name=a,l.value=this.request.data[a],s.appendChild(l)}for(var a in e.request.data){var l=document.createElement("input");l.type="hidden",l.name=a,l.value=e.request.data[a],s.appendChild(l)}var d=function(){var e;try{o.contentWindow&&(e=o.contentWindow.document)}catch(t){}if(!e)try{e=o.contentDocument?o.contentDocument:o.document}catch(t){e=o.document}return e&&e.body?e.body.innerHTML:null},u=function(r){switch(r.type){case"abort":e.errno="abort",e.error="Abort";break;case"error":var s=d();e.errno||(null===s?(e.errno="network",e.error="Network"):(e.errno="denied",e.error="Denied"));break;default:var s=d();e.errno||(null===s?(e.errno="network",e.error="Network"):(e.progress="100.00",e.success=!0))}if(e.active=!1,"undefined"!=typeof s){if(s&&"{"==s.substr(0,1)&&"}"==s.substr(s.length-1,1))try{s=JSON.parse(s)}catch(a){}e.data=s}i||(document.body.removeEventListener("keydown",n),document.body.removeEventListener("keydown",n),i=!0,o.parentNode&&o.parentNode.removeChild(o),e.removed||t.$dispatch("afterFileUpload",e,t),setTimeout(function(){t._fileUploads()},50))};setTimeout(function(){document.body.appendChild(o).appendChild(s).submit(),o.onload=u,o.onerror=u,o.onabort=u,e.active=!0,r.iframe=o,document.body.addEventListener("keydown",n);var i=setInterval(function(){t.active&&e.active&&!e.success&&!e.errno||(clearInterval(i),e.success||e.errno||o.onabort({type:"abort"}))},50);t.$dispatch("beforeFileUpload",e,this)},10)}}}},function(e,t,r){t=e.exports=r(3)(),t.push([e.id,".file-uploads-label{overflow:hidden;position:relative;text-align:center}.file-uploads-label span{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.file-uploads-label input{z-index:1;opacity:0;font-size:20em;top:0;left:0;right:0;bottom:0;position:absolute;width:100%;height:100%}.file-uploads-label.file-uploads-html5 input{width:1px!important;height:1px!important;top:-1px!important;left:-1px!important;right:auto!important;bottom:auto!important}",""])},function(e,t){e.exports=function(){var e=[];return e.toString=function(){for(var e=[],t=0;t {{title}} "},function(e,t,r){var i,n;r(7),i=r(1),n=r(4),e.exports=i||{},e.exports.__esModule&&(e.exports=e.exports["default"]),n&&(("function"==typeof e.exports?e.exports.options||(e.exports.options={}):e.exports).template=n)},function(e,t,r){function i(e,t){for(var r=0;r=0&&b.splice(t,1)}function a(e){var t=document.createElement("style");return t.type="text/css",o(e,t),t}function l(e,t){var r,i,n;if(t.singleton){var o=v++;r=m||(m=a(t)),i=d.bind(null,r,o,!1),n=d.bind(null,r,o,!0)}else r=a(t),i=u.bind(null,r),n=function(){s(r)};return i(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;i(e=t)}else n()}}function d(e,t,r,i){var n=r?"":i.css;if(e.styleSheet)e.styleSheet.cssText=g(t,n);else{var o=document.createTextNode(n),s=e.childNodes;s[t]&&e.removeChild(s[t]),s.length?e.insertBefore(o,s[t]):e.appendChild(o)}}function u(e,t){var r=t.css,i=t.media,n=t.sourceMap;if(i&&e.setAttribute("media",i),n&&(r+="\n/*# sourceURL="+n.sources[0]+" */",r+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(n))))+" */"),e.styleSheet)e.styleSheet.cssText=r;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(r))}}var p={},f=function(e){var t;return function(){return"undefined"==typeof t&&(t=e.apply(this,arguments)),t}},c=f(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),h=f(function(){return document.head||document.getElementsByTagName("head")[0]}),m=null,v=0,b=[];e.exports=function(e,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=c()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var r=n(e);return i(r,t),function(e){for(var o=[],s=0;s',\n\t methods: {\n\t change: function change(e) {\n\t this.$parent._addFileUploads(e.target);\n\t this.$destroy();\n\t }\n\t }\n\t }\n\t },\n\t\n\t data: function data() {\n\t return {\n\t files: [],\n\t active: false,\n\t uploaded: true,\n\t request: {\n\t data: {},\n\t headers: {}\n\t }\n\t };\n\t },\n\t init: function init() {\n\t var input = document.createElement('input');\n\t input.type = 'file';\n\t if (window.FormData && input.files) {\n\t this.$mode = 'html5';\n\t } else {\n\t this.$mode = 'html4';\n\t }\n\t this._index = 0;\n\t this._files = {};\n\t },\n\t\n\t watch: {\n\t files: function files(_files) {\n\t var ids = [];\n\t for (var i = 0; i < _files.length; i++) {\n\t var file = _files[i];\n\t if (!file.errno && !file.success) {\n\t this.uploaded = false;\n\t }\n\t ids.push(file.id);\n\t }\n\t for (var id in this._files) {\n\t if (ids.indexOf(id) != -1) {\n\t continue;\n\t }\n\t\n\t var file = this._files[id]._file;\n\t\n\t file.removed = true;\n\t var xhr = this._files[id].xhr;\n\t if (xhr) {\n\t xhr.abort();\n\t xhr.timeout = 1;\n\t }\n\t var iframe = this._files[id].iframe;\n\t if (iframe) {\n\t iframe.onabort({ type: 'abort' });\n\t }\n\t delete this._files[id];\n\t this.$dispatch('removeFileUpload', file, this);\n\t }\n\t this._index = 0;\n\t },\n\t active: function active(newValue, oldValue) {\n\t if (newValue && !oldValue) {\n\t this._fileUploads();\n\t }\n\t },\n\t uploaded: function uploaded(_uploaded) {\n\t if (_uploaded) {\n\t this.active = false;\n\t }\n\t }\n\t },\n\t\n\t methods: {\n\t _addFileUploads: function _addFileUploads(el) {\n\t var Component = this.$options.components.inputFile;\n\t new Component({\n\t parent: this,\n\t el: el\n\t });\n\t this.uploaded = false;\n\t\n\t if (el.files) {\n\t for (var i = 0; i < el.files.length; i++) {\n\t var file = el.files[i];\n\t var id = 'upload-file-' + Math.random().toString(36).substr(2);\n\t var value = { id: id, size: file.size, name: file.name, progress: '0.00', active: false, error: '', errno: '', success: false, data: {}, request: { headers: {}, data: {} } };\n\t this._files[id] = { el: el, file: file };\n\t\n\t var len;\n\t if (this.multiple) {\n\t len = this.files.push(value);\n\t } else {\n\t this.files = [value];\n\t len = 1;\n\t }\n\t this._files[id]._file = this.files[len - 1];\n\t this.$dispatch('addFileUpload', this.files[len - 1], this);\n\t }\n\t } else {\n\t var id = 'upload-file-' + Math.random().toString(36).substr(2);\n\t var value = { id: id, size: -1, name: el.value.replace(/^.*?([^\\/\\\\\\r\\n]+)$/, '$1'), progress: '0.00', active: false, error: '', errno: '', success: false, data: {}, request: { headers: {}, data: {} } };\n\t this._files[id] = { el: el };\n\t var len;\n\t if (this.multiple) {\n\t len = this.files.push(value);\n\t } else {\n\t this.files = [value];\n\t len = 1;\n\t }\n\t var len = this.files.push(file);\n\t this._files[id]._file = this.files[len - 1];\n\t this.$dispatch('addFileUpload', this.files[len - 1], this);\n\t }\n\t },\n\t _fileUploads: function _fileUploads() {\n\t if (!this.active) {\n\t return;\n\t }\n\t for (; this._index < this.files.length; this._index++) {\n\t var file = this.files[this._index];\n\t if (file.active || file.success || file.errno) {\n\t continue;\n\t }\n\t if (this.size && this.size > 0 && file.size >= 0 && file.size > this.size) {\n\t file.error = 'Size';\n\t file.errno = 'size';\n\t continue;\n\t }\n\t\n\t if (this.$mode == 'html5') {\n\t this._fileUploadHtml5(file);\n\t } else {\n\t this._fileUploadHtml4(file);\n\t }\n\t return;\n\t }\n\t this.active = false;\n\t this.uploaded = true;\n\t },\n\t _fileUploadHtml5: function _fileUploadHtml5(file) {\n\t var _self = this;\n\t var file2 = this._files[file.id];\n\t\n\t var fileUploads = false;\n\t\n\t var form = new window.FormData();\n\t form.append(this.name, file2.file);\n\t for (var key in this.request.data) {\n\t form.append(key, this.request.data[key]);\n\t }\n\t\n\t for (var key in file.request.data) {\n\t form.append(key, file.request.data[key]);\n\t }\n\t\n\t var xhr = new XMLHttpRequest();\n\t\n\t xhr.upload.onprogress = function (e) {\n\t if (file.removed) {\n\t xhr.abort();\n\t return;\n\t }\n\t if (!_self.active || !file.active) {\n\t xhr.abort();\n\t return;\n\t }\n\t if (e.lengthComputable) {\n\t file.progress = (e.loaded / e.total * 100).toFixed(2);\n\t }\n\t _self.$dispatch('fileUploadProgress', file, _self);\n\t };\n\t\n\t var callback = function callback(e) {\n\t switch (e.type) {\n\t case 'timeout':\n\t file.errno = 'timeout';\n\t file.error = 'Timeout';\n\t break;\n\t case 'abort':\n\t file.errno = 'abort';\n\t file.error = 'Abort';\n\t break;\n\t case 'error':\n\t if (!xhr.status) {\n\t file.errno = 'network';\n\t file.error = 'Network';\n\t } else if (xhr.status >= 500) {\n\t file.errno = 'server';\n\t file.error = 'Server';\n\t } else if (xhr.status >= 400) {\n\t file.errno = 'denied';\n\t file.error = 'Denied';\n\t }\n\t break;\n\t default:\n\t if (xhr.status >= 500) {\n\t file.errno = 'server';\n\t file.error = 'Server';\n\t } else if (xhr.status >= 400) {\n\t file.errno = 'denied';\n\t file.error = 'Denied';\n\t } else {\n\t file.progress = '100.00';\n\t file.success = true;\n\t }\n\t }\n\t file.active = false;\n\t if (xhr.responseText) {\n\t var contentType = xhr.getResponseHeader('Content-Type');\n\t if (contentType && contentType.indexOf('/json') != -1) {\n\t file.data = JSON.parse(xhr.responseText);\n\t } else {\n\t file.data = xhr.responseText;\n\t }\n\t }\n\t if (!fileUploads) {\n\t fileUploads = true;\n\t if (!file.removed) {\n\t _self.$dispatch('afterFileUpload', file, _self);\n\t }\n\t setTimeout(function () {\n\t _self._fileUploads();\n\t }, 50);\n\t }\n\t };\n\t\n\t xhr.onload = callback;\n\t xhr.onerror = callback;\n\t xhr.onabort = callback;\n\t xhr.ontimeout = callback;\n\t\n\t if (this.timeout) {\n\t xhr.timeout = this.timeout;\n\t }\n\t\n\t xhr.open('POST', this.action);\n\t\n\t for (var key in this.request.headers) {\n\t xhr.setRequestHeader(key, this.request.headers[key]);\n\t }\n\t\n\t for (var key in file.request.headers) {\n\t xhr.setRequestHeader(key, file.request.headers[key]);\n\t }\n\t\n\t xhr.send(form);\n\t\n\t file.active = true;\n\t\n\t file2.xhr = xhr;\n\t\n\t var interval = setInterval(function () {\n\t if (!_self.active || !file.active || file.success || file.errno) {\n\t clearInterval(interval);\n\t if (!file.success && !file.errno) {\n\t xhr.abort();\n\t }\n\t }\n\t }, 50);\n\t this.$dispatch('beforeFileUpload', file, this);\n\t },\n\t _fileUploadHtml4: function _fileUploadHtml4(file) {\n\t var _self = this;\n\t var file2 = this._files[file.id];\n\t\n\t var fileUploads = false;\n\t\n\t var keydown = function keydown(e) {\n\t if (e.keyCode == 27) {\n\t e.preventDefault();\n\t }\n\t };\n\t\n\t var iframe = document.createElement('iframe');\n\t iframe.id = 'upload-iframe-' + file.id;\n\t iframe.name = 'upload-iframe-' + file.id;\n\t iframe.src = 'about:blank';\n\t iframe.style.width = '1px';\n\t iframe.style.height = '1px';\n\t iframe.style.top = '-9999px';\n\t iframe.style.left = '-9999px';\n\t iframe.style.position = 'absolute';\n\t iframe.style.marginTop = '-9999em';\n\t\n\t var form = document.createElement('form');\n\t form.action = this.action;\n\t form.name = 'upload-form-' + file.id;\n\t form.setAttribute('method', 'POST');\n\t form.setAttribute('target', 'upload-iframe-' + file.id);\n\t form.setAttribute('enctype', 'multipart/form-data');\n\t form.appendChild(file2.el);\n\t for (var key in this.request.data) {\n\t var input = document.createElement('input');\n\t input.type = 'hidden';\n\t input.name = key;\n\t input.value = this.request.data[key];\n\t form.appendChild(input);\n\t }\n\t\n\t for (var key in file.request.data) {\n\t var input = document.createElement('input');\n\t input.type = 'hidden';\n\t input.name = key;\n\t input.value = file.request.data[key];\n\t form.appendChild(input);\n\t }\n\t\n\t var getDocumentData = function getDocumentData() {\n\t var doc;\n\t try {\n\t if (iframe.contentWindow) {\n\t doc = iframe.contentWindow.document;\n\t }\n\t } catch (err) {}\n\t if (!doc) {\n\t try {\n\t doc = iframe.contentDocument ? iframe.contentDocument : iframe.document;\n\t } catch (err) {\n\t doc = iframe.document;\n\t }\n\t }\n\t if (doc && doc.body) {\n\t return doc.body.innerHTML;\n\t }\n\t return null;\n\t };\n\t\n\t var callback = function callback(e) {\n\t switch (e.type) {\n\t case 'abort':\n\t file.errno = 'abort';\n\t file.error = 'Abort';\n\t break;\n\t case 'error':\n\t var data = getDocumentData();\n\t if (file.errno) {} else if (data === null) {\n\t file.errno = 'network';\n\t file.error = 'Network';\n\t } else {\n\t file.errno = 'denied';\n\t file.error = 'Denied';\n\t }\n\t break;\n\t default:\n\t var data = getDocumentData();\n\t if (file.errno) {} else if (data === null) {\n\t file.errno = 'network';\n\t file.error = 'Network';\n\t } else {\n\t file.progress = '100.00';\n\t file.success = true;\n\t }\n\t }\n\t\n\t file.active = false;\n\t if (typeof data != \"undefined\") {\n\t if (data && data.substr(0, 1) == '{' && data.substr(data.length - 1, 1) == '}') {\n\t try {\n\t data = JSON.parse(data);\n\t } catch (err) {}\n\t }\n\t file.data = data;\n\t }\n\t if (!fileUploads) {\n\t document.body.removeEventListener('keydown', keydown);\n\t document.body.removeEventListener('keydown', keydown);\n\t fileUploads = true;\n\t iframe.parentNode && iframe.parentNode.removeChild(iframe);\n\t if (!file.removed) {\n\t _self.$dispatch('afterFileUpload', file, _self);\n\t }\n\t setTimeout(function () {\n\t _self._fileUploads();\n\t }, 50);\n\t }\n\t };\n\t\n\t setTimeout(function () {\n\t document.body.appendChild(iframe).appendChild(form).submit();\n\t iframe.onload = callback;\n\t iframe.onerror = callback;\n\t iframe.onabort = callback;\n\t\n\t file.active = true;\n\t\n\t file2.iframe = iframe;\n\t\n\t document.body.addEventListener('keydown', keydown);\n\t var interval = setInterval(function () {\n\t if (!_self.active || !file.active || file.success || file.errno) {\n\t clearInterval(interval);\n\t if (!file.success && !file.errno) {\n\t iframe.onabort({ type: 'abort' });\n\t }\n\t }\n\t }, 50);\n\t _self.$dispatch('beforeFileUpload', file, this);\n\t }, 10);\n\t }\n\t }\n\t};\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\texports = module.exports = __webpack_require__(3)();\n\t// imports\n\t\n\t\n\t// module\n\texports.push([module.id, \".file-uploads-label{overflow:hidden;position:relative;text-align:center}.file-uploads-label span{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.file-uploads-label input{z-index:1;opacity:0;font-size:20em;top:0;left:0;right:0;bottom:0;position:absolute;width:100%;height:100%}.file-uploads-label.file-uploads-html5 input{width:1px!important;height:1px!important;top:-1px!important;left:-1px!important;right:auto!important;bottom:auto!important}\", \"\"]);\n\t\n\t// exports\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\t/*\r\n\t\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\t\tAuthor Tobias Koppers @sokra\r\n\t*/\r\n\t// css base code, injected by the css-loader\r\n\tmodule.exports = function() {\r\n\t\tvar list = [];\r\n\t\r\n\t\t// return the list of modules as css string\r\n\t\tlist.toString = function toString() {\r\n\t\t\tvar result = [];\r\n\t\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\t\tvar item = this[i];\r\n\t\t\t\tif(item[2]) {\r\n\t\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t\t} else {\r\n\t\t\t\t\tresult.push(item[1]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result.join(\"\");\r\n\t\t};\r\n\t\r\n\t\t// import a list of modules into the list\r\n\t\tlist.i = function(modules, mediaQuery) {\r\n\t\t\tif(typeof modules === \"string\")\r\n\t\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\t\tvar alreadyImportedModules = {};\r\n\t\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\t\tvar id = this[i][0];\r\n\t\t\t\tif(typeof id === \"number\")\r\n\t\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t\t}\r\n\t\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\t\tvar item = modules[i];\r\n\t\t\t\t// skip already imported module\r\n\t\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t\t}\r\n\t\t\t\t\tlist.push(item);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\t\treturn list;\r\n\t};\r\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\tmodule.exports = \"
\";\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __vue_script__, __vue_template__\n\t__webpack_require__(7)\n\t__vue_script__ = __webpack_require__(1)\n\t__vue_template__ = __webpack_require__(4)\n\tmodule.exports = __vue_script__ || {}\n\tif (module.exports.__esModule) module.exports = module.exports.default\n\tif (__vue_template__) {\n\t(typeof module.exports === \"function\" ? (module.exports.options || (module.exports.options = {})) : module.exports).template = __vue_template__\n\t}\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/*\n\t\tMIT License http://www.opensource.org/licenses/mit-license.php\n\t\tAuthor Tobias Koppers @sokra\n\t*/\n\tvar stylesInDom = {},\n\t\tmemoize = function(fn) {\n\t\t\tvar memo;\n\t\t\treturn function () {\n\t\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\t\treturn memo;\n\t\t\t};\n\t\t},\n\t\tisOldIE = memoize(function() {\n\t\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t\t}),\n\t\tgetHeadElement = memoize(function () {\n\t\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t\t}),\n\t\tsingletonElement = null,\n\t\tsingletonCounter = 0,\n\t\tstyleElementsInsertedAtTop = [];\n\t\n\tmodule.exports = function(list, options) {\n\t\tif(false) {\n\t\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t\t}\n\t\n\t\toptions = options || {};\n\t\t// Force single-tag solution on IE6-9, which has a hard limit on the # of \n\n\n\n\n\n/** WEBPACK FOOTER **\n ** FileUpload.vue?5e2c3488\n **/","exports = module.exports = require(\"./../node_modules/css-loader/lib/css-base.js\")();\n// imports\n\n\n// module\nexports.push([module.id, \".file-uploads-label{overflow:hidden;position:relative;text-align:center}.file-uploads-label span{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.file-uploads-label input{z-index:1;opacity:0;font-size:20em;top:0;left:0;right:0;bottom:0;position:absolute;width:100%;height:100%}.file-uploads-label.file-uploads-html5 input{width:1px!important;height:1px!important;top:-1px!important;left:-1px!important;right:auto!important;bottom:auto!important}\", \"\"]);\n\n// exports\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader!./~/vue-loader/lib/style-rewriter.js!./~/vue-loader/lib/selector.js?type=style&index=0!./src/FileUpload.vue\n ** module id = 2\n ** module chunks = 0\n **/","/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push(\"@media \" + item[2] + \"{\" + item[1] + \"}\");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join(\"\");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === \"string\")\r\n\t\t\tmodules = [[null, modules, \"\"]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === \"number\")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== \"number\" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = \"(\" + item[2] + \") and (\" + mediaQuery + \")\";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/css-loader/lib/css-base.js\n ** module id = 3\n ** module chunks = 0\n **/","module.exports = \"
\";\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/FileUpload.vue\n ** module id = 4\n ** module chunks = 0\n **/","var __vue_script__, __vue_template__\nrequire(\"!!vue-style-loader!css-loader!./../node_modules/vue-loader/lib/style-rewriter.js!./../node_modules/vue-loader/lib/selector.js?type=style&index=0!./FileUpload.vue\")\n__vue_script__ = require(\"!!babel-loader?presets[]=es2015&plugins[]=transform-runtime&comments=false!./../node_modules/vue-loader/lib/selector.js?type=script&index=0!./FileUpload.vue\")\n__vue_template__ = require(\"!!vue-html-loader!./../node_modules/vue-loader/lib/selector.js?type=template&index=0!./FileUpload.vue\")\nmodule.exports = __vue_script__ || {}\nif (module.exports.__esModule) module.exports = module.exports.default\nif (__vue_template__) {\n(typeof module.exports === \"function\" ? (module.exports.options || (module.exports.options = {})) : module.exports).template = __vue_template__\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/FileUpload.vue\n ** module id = 5\n ** module chunks = 0\n **/","/*\n\tMIT License http://www.opensource.org/licenses/mit-license.php\n\tAuthor Tobias Koppers @sokra\n*/\nvar stylesInDom = {},\n\tmemoize = function(fn) {\n\t\tvar memo;\n\t\treturn function () {\n\t\t\tif (typeof memo === \"undefined\") memo = fn.apply(this, arguments);\n\t\t\treturn memo;\n\t\t};\n\t},\n\tisOldIE = memoize(function() {\n\t\treturn /msie [6-9]\\b/.test(window.navigator.userAgent.toLowerCase());\n\t}),\n\tgetHeadElement = memoize(function () {\n\t\treturn document.head || document.getElementsByTagName(\"head\")[0];\n\t}),\n\tsingletonElement = null,\n\tsingletonCounter = 0,\n\tstyleElementsInsertedAtTop = [];\n\nmodule.exports = function(list, options) {\n\tif(typeof DEBUG !== \"undefined\" && DEBUG) {\n\t\tif(typeof document !== \"object\") throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n\t}\n\n\toptions = options || {};\n\t// Force single-tag solution on IE6-9, which has a hard limit on the # of + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IndexNameSizeProgressActiveErrorErrnoSuccessAbortDelete
{{$index}}{{file.name}}{{file.size}}{{file.progress}}{{file.active}}{{file.error}}{{file.errno}}{{file.success}}Abortx
+
+
+ + + + + + + + + + + +
+ + + + + + Accept: + + Max file size: + + Multiple: + + Status: Active: {{$refs.upload.active}}, Uploaded: {{$refs.upload.uploaded}} +
+
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..4a33212 --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "vue-upload-component", + "description": "Vue.js file upload component, Support for multiple file uploads, progress, html4, ie9", + "version": "0.1.0", + "author": "LianYue", + "scripts": { + "dev": "webpack-dev-server --inline --hot", + "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" + }, + "main": "/src/FileUpload.vue", + "repository": { + "type": "git", + "url": "git+https://github.com/lian-yue/vue-upload-component.git" + }, + "keywords": [ + "Vue.js", + "File", + "Upload", + "Uploads", + "Multiple", + "Component" + ], + "author": "LianYue", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/lian-yue/vue-upload-component/issues" + }, + "homepage": "https://github.com/lian-yue/vue-upload-component#readme", + "dependencies": { + "babel-runtime": "^6.0.0" + }, + "devDependencies": { + "babel-core": "^6.0.0", + "babel-loader": "^6.0.0", + "babel-plugin-transform-runtime": "^6.0.0", + "babel-preset-es2015": "^6.0.0", + "babel-preset-stage-2": "^6.0.0", + "cross-env": "^1.0.6", + "css-loader": "^0.23.0", + "file-loader": "^0.8.4", + "json-loader": "^0.5.4", + "url-loader": "^0.5.7", + "vue-hot-reload-api": "^1.2.0", + "vue-html-loader": "^1.0.0", + "vue-loader": "^8.2.1", + "vue-style-loader": "^1.0.0", + "webpack": "^1.12.2", + "webpack-dev-server": "^1.12.0" + } +} diff --git a/src/fileUpload.vue b/src/fileUpload.vue new file mode 100644 index 0000000..cfa70ba --- /dev/null +++ b/src/fileUpload.vue @@ -0,0 +1,508 @@ + + + + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..33eddb1 --- /dev/null +++ b/src/main.js @@ -0,0 +1,28 @@ +var FileUpload = require('./FileUpload.vue'); + +new Vue({ + el:'#app', + components: { + FileUpload:FileUpload, + }, + data: { + accept: 'image/*', + size: 1024 * 1024 * 10, + multiple: true, + }, + compiled: function() { + this.$refs.upload.request = { + headers: { + "X-Csrf-Token": "xxxx", + }, + data: { + "_csrf_token": "xxxxxx", + }, + }; + }, + methods: { + remove: function(file) { + this.$refs.upload.files.$remove(file); + }, + } +}); diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..b9afa61 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,66 @@ +var path = require('path') +var webpack = require('webpack') + +module.exports = { + entry: './src/main.js', + output: { + path: path.resolve(__dirname, './dist'), + publicPath: '/dist/', + filename: 'build.js' + }, + resolveLoader: { + root: path.join(__dirname, 'node_modules'), + }, + module: { + loaders: [ + { + test: /\.vue$/, + loader: 'vue' + }, + { + test: /\.js$/, + loader: 'babel', + exclude: /node_modules/ + }, + { + test: /\.json$/, + loader: 'json' + }, + { + test: /\.html$/, + loader: 'vue-html' + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: 'url', + query: { + limit: 10000, + name: '[name].[ext]?[hash]' + } + } + ] + }, + devServer: { + historyApiFallback: true, + noInfo: true + }, + devtool: '#eval-source-map' +} + +if (process.env.NODE_ENV === 'production') { + module.exports.devtool = '#source-map' + // http://vuejs.github.io/vue-loader/workflow/production.html + module.exports.plugins = (module.exports.plugins || []).concat([ + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"' + } + }), + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + } + }), + new webpack.optimize.OccurenceOrderPlugin() + ]) +}