UNPKG

@robertklein.sk/vue-upload-component

Version:

Vue.js file upload component, Multi-file upload, Upload directory, Drag upload, Drag the directory, Upload multiple files at the same time, html4 (IE 9), `PUT` method, Customize the filter

5 lines 146 kB
/*! * Name: @robertklein.sk/vue-upload-component * Version: 2.8.22 * Author: LianYue */!function(e){var n={};function t(i){if(n[i])return n[i].exports;var a=n[i]={i:i,l:!1,exports:{}};return e[i].call(a.exports,a,a.exports,t),a.l=!0,a.exports}t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:i})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var a in e)t.d(i,a,function(n){return e[n]}.bind(null,a));return i},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/dist",t(t.s=26)}([function(e,n,t){"use strict";function i(e,n,t,i,a,o,s,r){var l,u="function"==typeof e?e.options:e;if(n&&(u.render=n,u.staticRenderFns=t,u._compiled=!0),i&&(u.functional=!0),o&&(u._scopeId="data-v-"+o),s?(l=function(e){(e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),a&&a.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(s)},u._ssrRegister=l):a&&(l=r?function(){a.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:a),l)if(u.functional){u._injectStyles=l;var d=u.render;u.render=function(e,n){return l.call(n),d(e,n)}}else{var p=u.beforeCreate;u.beforeCreate=p?[].concat(p,l):[l]}return{exports:e,options:u}}t.d(n,"a",(function(){return i}))},function(e,n,t){e.exports=t(51)},function(e,n){e.exports=function(e){var n=[];return n.toString=function(){return this.map((function(n){var t=function(e,n){var t=e[1]||"",i=e[3];if(!i)return t;if(n&&"function"==typeof btoa){var a=(s=i,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(s))))+" */"),o=i.sources.map((function(e){return"/*# sourceURL="+i.sourceRoot+e+" */"}));return[t].concat(o).concat([a]).join("\n")}var s;return[t].join("\n")}(n,e);return n[2]?"@media "+n[2]+"{"+t+"}":t})).join("")},n.i=function(e,t){"string"==typeof e&&(e=[[null,e,""]]);for(var i={},a=0;a<this.length;a++){var o=this[a][0];"number"==typeof o&&(i[o]=!0)}for(a=0;a<e.length;a++){var s=e[a];"number"==typeof s[0]&&i[s[0]]||(t&&!s[2]?s[2]=t:t&&(s[2]="("+s[2]+") and ("+t+")"),n.push(s))}},n}},function(e,n,t){"use strict";t.r(n),t.d(n,"default",(function(){return m}));var i=t(9),a=t.n(i),o="undefined"!=typeof document;if("undefined"!=typeof DEBUG&&DEBUG&&!o)throw new Error("vue-style-loader cannot be used in a non-browser environment. Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.");var s={},r=o&&(document.head||document.getElementsByTagName("head")[0]),l=null,u=0,d=!1,p=function(){},c=null,f="undefined"!=typeof navigator&&/msie [6-9]\b/.test(navigator.userAgent.toLowerCase());function m(e,n,t,i){d=t,c=i||{};var o=a()(e,n);return h(o),function(n){for(var t=[],i=0;i<o.length;i++){var r=o[i];(l=s[r.id]).refs--,t.push(l)}n?h(o=a()(e,n)):o=[];for(i=0;i<t.length;i++){var l;if(0===(l=t[i]).refs){for(var u=0;u<l.parts.length;u++)l.parts[u]();delete s[l.id]}}}}function h(e){for(var n=0;n<e.length;n++){var t=e[n],i=s[t.id];if(i){i.refs++;for(var a=0;a<i.parts.length;a++)i.parts[a](t.parts[a]);for(;a<t.parts.length;a++)i.parts.push(b(t.parts[a]));i.parts.length>t.parts.length&&(i.parts.length=t.parts.length)}else{var o=[];for(a=0;a<t.parts.length;a++)o.push(b(t.parts[a]));s[t.id]={id:t.id,refs:1,parts:o}}}}function v(){var e=document.createElement("style");return e.type="text/css",r.appendChild(e),e}function b(e){var n,t,i=document.querySelector('style[data-vue-ssr-id~="'+e.id+'"]');if(i){if(d)return p;i.parentNode.removeChild(i)}if(f){var a=u++;i=l||(l=v()),n=_.bind(null,i,a,!1),t=_.bind(null,i,a,!0)}else i=v(),n=x.bind(null,i),t=function(){i.parentNode.removeChild(i)};return n(e),function(i){if(i){if(i.css===e.css&&i.media===e.media&&i.sourceMap===e.sourceMap)return;n(e=i)}else t()}}var g,y=(g=[],function(e,n){return g[e]=n,g.filter(Boolean).join("\n")});function _(e,n,t,i){var a=t?"":i.css;if(e.styleSheet)e.styleSheet.cssText=y(n,a);else{var o=document.createTextNode(a),s=e.childNodes;s[n]&&e.removeChild(s[n]),s.length?e.insertBefore(o,s[n]):e.appendChild(o)}}function x(e,n){var t=n.css,i=n.media,a=n.sourceMap;if(i&&e.setAttribute("media",i),c.ssrId&&e.setAttribute("data-vue-ssr-id",n.id),a&&(t+="\n/*# sourceURL="+a.sources[0]+" */",t+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(a))))+" */"),e.styleSheet)e.styleSheet.cssText=t;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(t))}}},function(e,n){e.exports=Vue},function(e,n){e.exports=marked},function(e,n){e.exports=Vuex},function(e,n){e.exports=Cropper},function(e,n){e.exports=hljs},function(e,n,t){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(e,n){for(var t=[],i={},a=0;a<n.length;a++){var o=n[a],s=o[0],r=o[1],l=o[2],u=o[3],d={id:e+":"+a,css:r,media:l,sourceMap:u};i[s]?i[s].parts.push(d):t.push(i[s]={id:s,parts:[d]})}return t}},function(e,n){e.exports='\n> **The document uses Google Translate**\n\n## Getting Started\n\n### NPM\n\n``` bash\nnpm install vue-upload-component --save\n```\n\n``` js\nconst VueUploadComponent = require(\'vue-upload-component\')\nVue.component(\'file-upload\', VueUploadComponent)\n```\n\n### Curated\n\n**No data**\n\n\n### Script\n\n\nunpkg\n\n``` html\n<script src="https://unpkg.com/vue"><\/script>\n<script src="https://unpkg.com/vue-upload-component"><\/script>\n<script>\nVue.component(\'file-upload\', VueUploadComponent)\n<\/script>\n```\n\njsDelivr\n\n``` html\n<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"><\/script>\n<script src="https://cdn.jsdelivr.net/npm/vue-upload-component"><\/script>\n<script>\nVue.component(\'file-upload\', VueUploadComponent)\n<\/script>\n```\n\n\n### Simple example\n\n\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <title>Vue-upload-component Test</title>\n <script src="https://unpkg.com/vue"><\/script>\n <script src="https://unpkg.com/vue-upload-component"><\/script>\n</head>\n<body>\n<div id="app">\n <ul>\n <li v-for="file in files">{{file.name}} - Error: {{file.error}}, Success: {{file.success}}</li>\n </ul>\n <file-upload\n ref="upload"\n v-model="files"\n post-action="/post.method"\n put-action="/put.method"\n @input-file="inputFile"\n @input-filter="inputFilter"\n >\n Upload file\n </file-upload>\n <button v-show="!$refs.upload || !$refs.upload.active" @click.prevent="$refs.upload.active = true" type="button">Start upload</button>\n <button v-show="$refs.upload && $refs.upload.active" @click.prevent="$refs.upload.active = false" type="button">Stop upload</button>\n</div>\n<script>\nnew Vue({\n el: \'#app\',\n data: function () {\n return {\n files: []\n }\n },\n components: {\n FileUpload: VueUploadComponent\n },\n methods: {\n /**\n * Has changed\n * @param Object|undefined newFile Read only\n * @param Object|undefined oldFile Read only\n * @return undefined\n */\n inputFile: function (newFile, oldFile) {\n if (newFile && oldFile && !newFile.active && oldFile.active) {\n // Get response data\n console.log(\'response\', newFile.response)\n if (newFile.xhr) {\n // Get the response status code\n console.log(\'status\', newFile.xhr.status)\n }\n }\n },\n /**\n * Pretreatment\n * @param Object|undefined newFile Read and write\n * @param Object|undefined oldFile Read only\n * @param Function prevent Prevent changing\n * @return undefined\n */\n inputFilter: function (newFile, oldFile, prevent) {\n if (newFile && !oldFile) {\n // Filter non-image file\n if (!/\\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(newFile.name)) {\n return prevent()\n }\n }\n\n // Create a blob field\n newFile.blob = \'\'\n let URL = window.URL || window.webkitURL\n if (URL && URL.createObjectURL) {\n newFile.blob = URL.createObjectURL(newFile.file)\n }\n }\n }\n});\n<\/script>\n</body>\n</html>\n```\n\n### Chunk Upload\n\nThis package allows chunk uploads, which means you can upload a file in different parts.\n\nThis process is divided in three phases: <strong>start</strong>, <strong>upload</strong>,<strong>finish</strong></p>\n\n#### start\n\nThis is the first phase of the process. We\'ll tell the backend that we are going to upload a file, with certain `size`, `name` and `mime_type`.\n\nUse the option `startBody` to add more parameters to the body of this request.\n\nThe backend should provide a `session_id` (to identify the upload) and a `end_offset` which is the size of every chunk\n\n##### HTTP start phase example\n\nRequest body example:\n```\n{\n "phase": "start",\n "mime_type": "image/png",\n "size": 12669430,\n "name":"hubbleimage1stscihp1809af6400x4800.png"\n}\n```\n\nResponse body example:\n```\n{\n  "data": {\n    "end_offset": 6291456,\n    "session_id": "61db8102-fca6-44ae-81e2-a499d438e7a5"\n  },\n  "status": "success"\n}\n\n```\n\n#### upload\n\nIn this phase we\'ll upload every chunk until all of them are uploaded. This step allows some failures in the backend, and will retry up to `maxRetries` times.\n\nWe\'ll send the `session_id`, `start_offset` and `chunk` (the sliced blob - part of file we are uploading). We expect the backend to return `{ status: \'success\' }`, we\'ll retry otherwise.\n\nUse the option `uploadBody` to add more parameters to the body of this request.\n\n##### HTTP upload phase example with 3 chunks\n\nRequest body example - chunk 1 from 3:\n```\n------WebKitFormBoundaryuI0uiY8h7MCbcysx\nContent-Disposition: form-data; name="phase"\n\nupload\n------WebKitFormBoundaryuI0uiY8h7MCbcysx\nContent-Disposition: form-data; name="session_id"\n\n61db8102-fca6-44ae-81e2-a499d438e7a5\n------WebKitFormBoundaryuI0uiY8h7MCbcysx\nContent-Disposition: form-data; name="start_offset"\n\n0\n------WebKitFormBoundaryuI0uiY8h7MCbcysx\nContent-Disposition: form-data; name="chunk"; filename="blob"\nContent-Type: application/octet-stream\n\n\n------WebKitFormBoundaryuI0uiY8h7MCbcysx--\n```\n\nResponse body example - chunk 1 from 3:\n```\n{\n  "status": "success"\n}\n```\n\nRequest body example - chunk 2 from 3:\n```\n------WebKitFormBoundary4cjBupFqrx1SrHoR\nContent-Disposition: form-data; name="phase"\n\nupload\n------WebKitFormBoundary4cjBupFqrx1SrHoR\nContent-Disposition: form-data; name="session_id"\n\n61db8102-fca6-44ae-81e2-a499d438e7a5\n------WebKitFormBoundary4cjBupFqrx1SrHoR\nContent-Disposition: form-data; name="start_offset"\n\n6291456\n------WebKitFormBoundary4cjBupFqrx1SrHoR\nContent-Disposition: form-data; name="chunk"; filename="blob"\nContent-Type: application/octet-stream\n\n\n------WebKitFormBoundary4cjBupFqrx1SrHoR-\n```\n\nResponse body example - chunk 2 from 3:\n```\n{\n  "status": "success"\n}\n```\n\nRequest body example - chunk 3 from 3:\n```\n------WebKitFormBoundarypWxg4xnB5QBDoFys\nContent-Disposition: form-data; name="phase"\n\nupload\n------WebKitFormBoundarypWxg4xnB5QBDoFys\nContent-Disposition: form-data; name="session_id"\n\n61db8102-fca6-44ae-81e2-a499d438e7a5\n------WebKitFormBoundarypWxg4xnB5QBDoFys\nContent-Disposition: form-data; name="start_offset"\n\n12582912\n------WebKitFormBoundarypWxg4xnB5QBDoFys\nContent-Disposition: form-data; name="chunk"; filename="blob"\nContent-Type: application/octet-stream\n\n\n------WebKitFormBoundarypWxg4xnB5QBDoFys--\n```\n\nResponse body example - chunk 1 from 3:\n```\n{\n  "status": "success"\n}\n```\n\n#### finish\n\nIn this phase we tell the backend that there are no more chunks to upload, so it can wrap everything. We send the `session_id` in this phase.\n\nUse the option `finishBody` to add more parameters to the body of this request.\n\n##### HTTP finish phase example\n\nRequest body example:\n```\n{\n "phase": "finish",\n "session_id": "61db8102-fca6-44ae-81e2-a499d438e7a5"\n}\n```\n\nResponse body example:\n```\n{\n  "status": "success"\n}\n```\n\n#### Example\n\nIn the following example we are going to add `Chunk Upload Functionality`. This component will use `Chunk Upload` when the size of the file is > `1MB`, it will behave as the `Simple example` when the size of the file is lower.\n\n```html\n <file-upload\n ref="upload"\n v-model="files"\n post-action="/post.method"\n put-action="/put.method"\n\n chunk-enabled\n :chunk="{\n action: \'/upload/chunk\',\n minSize: 1048576,\n maxActive: 3,\n maxRetries: 5,\n\n // Example in the case your backend also needs the user id to operate\n startBody: {\n user_id: user.id\n }\n }"\n\n @input-file="inputFile"\n @input-filter="inputFilter"\n >\n Upload file\n </file-upload>\n```\n\n#### Extending the handler\n\nWe are using the class `src/chunk/ChunkUploadHandler` class to implement this protocol. You can extend this class (or even create a different one from scratch) to implement your own way to communicat with the backend.\n\nThis class must implement a method called `upload` which **must** return a promise. This promise will be used by the `FileUpload` component to determinate whether the file was uploaded or failed.\n\nUse the `handler` parameter to use a different Handler\n\n```html\n :chunk="{\n action: \'/upload/chunk\',\n minSize: 1048576,\n maxActive: 3,\n maxRetries: 5,\n\n handler: MyHandlerClass\n }\n```\n\n### SSR (Server isomorphism)\n\n\n```html\n<template>\n <file-upload v-model="files" post-action="/">Upload file</file-upload>\n</template>\n<style>\n/*\nimport \'~vue-upload-component/dist/vue-upload-component.part.css\'\n@import "~vue-upload-component/dist/vue-upload-component.part.css";\n\n\nor\n\n\n */\n.file-uploads {\n overflow: hidden;\n position: relative;\n text-align: center;\n display: inline-block;\n}\n.file-uploads.file-uploads-html4 input[type="file"] {\n opacity: 0;\n font-size: 20em;\n z-index: 1;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.file-uploads.file-uploads-html5 input[type="file"] {\n overflow: hidden;\n position: fixed;\n width: 1px;\n height: 1px;\n z-index: -1;\n opacity: 0;\n}\n</style>\n<script>\nimport FileUpload from \'vue-upload-component/dist/vue-upload-component.part.js\'\nexport default {\n components: {\n FileUpload,\n },\n data() {\n return {\n files: []\n }\n },\n}\n<\/script>\n```\n\n\n** OR **\n\n\n```js\nimport FileUpload from \'vue-upload-component/src\'\n```\n\n\nwebpack.config.js\n\n```js\nconst nodeExternals = require(\'webpack-node-externals\');\n{\n //.....\n externals: [\n nodeExternals({whitelist:[/^vue-upload-component\\/src/]})\n ]\n //.....\n}\n```\n\n* [https://github.com/liady/webpack-node-externals](https://github.com/liady/webpack-node-externals)\n\n* [**`vue-hackernews` demo**](https://github.com/lian-yue/vue-hackernews-2.0/)\n\n* [**View changes**](https://github.com/lian-yue/vue-hackernews-2.0/commit/bd6c58a30cc6b8ba6c0148e737b3ce9336b99cf8)\n\n\n\n\n## Options / Props\n\n\n### input-id\n\nThe `id` attribute of the input tag\n\n* **Type:** `String`\n\n* **Default:** `this.name`\n\n* **Usage:**\n ```html\n <file-upload input-id="file2"></file-upload>\n \x3c!--Output--\x3e\n <input id="file2" />\n ```\n\n\n\n\n\n### name\n\nThe `name` attribute of the input tag\n\n* **Type:** `String`\n\n* **Default:** `file`\n\n* **Usage:**\n ```html\n <file-upload name="file"></file-upload>\n \x3c!--Output--\x3e\n <input name="file" />\n ```\n\n\n\n\n\n### post-action\n\n`POST` Request upload URL\n\n* **Type:** `String`\n\n* **Default:** `undefined`\n\n* **Usage:**\n ```html\n <file-upload post-action="/upload/post.php"></file-upload>\n ```\n\n\n\n\n\n### put-action\n\n`PUT` Request upload URL\n\n* **Type:** `String`\n\n* **Default:** `undefined`\n\n* **Browser:** `> IE9`\n\n* **Details:**\n\n `put-action` is not empty Please give priority to` PUT` request\n\n* **Usage:**\n ```html\n <file-upload put-action="/upload/put.php"></file-upload>\n ```\n\n\n\n### custom-action\n\nCustom upload method\n\n* **Type:** `async Function`\n\n* **Default:** `undefined`\n\n* **Details:** \n\n `custom-action` priority than `put-action, post-action`\n\n* **Usage:**\n ```html\n <file-upload :custom-action="customAction"></file-upload>\n ```\n ```js\n async function customAction(file, component) {\n // return await component.uploadPut(file)\n return await component.uploadHtml4(file)\n }\n ```\n\n\n\n\n\n### headers\n\nAttach `header` data\n\n* **Type:** `Object`\n\n* **Default:** `{}`\n\n* **Browser:** `> IE9`\n\n* **Usage:**\n ```html\n <file-upload :headers="{\'X-Token-CSRF\': \'code\'}"></file-upload>\n ```\n\n\n\n\n\n### data\n\n`POST request`: Append request `body`\n`PUT request`: Append request `query`\n\n* **Type:** `Object`\n\n* **Default:** `{}`\n\n* **Usage:**\n ```html\n <file-upload :data="{access_token: \'access_token\'}"></file-upload>\n ```\n\n\n\n\n### value, v-model\n\nFile List\n\n* **Type:** `Array<File | Object>`\n\n* **Default:** `[]`\n\n* **Details:**\n\n View **[`File`](#file)** details\n > In order to prevent unpredictable errors, can not directly modify the `files`, please use [`add`](#instance-methods-add), [`update`](#instance-methods-update), [`remove`](#instance-methods-remove) method to modify\n\n* **Usage:**\n ```html\n <file-upload :value="files" @input="updatetValue"></file-upload>\n \x3c!--or--\x3e\n <file-upload v-model="files"></file-upload>\n ```\n\n\n\n\n\n### accept\n\nThe `accept` attribute of the input tag, MIME type\n\n* **Type:** `String`\n\n* **Default:** `undefined`\n\n* **Browser:** `> IE9`\n\n* **Usage:**\n ```html\n <file-upload accept="image/png,image/gif,image/jpeg,image/webp"></file-upload>\n \x3c!--or--\x3e\n <file-upload accept="image/*"></file-upload>\n ```\n\n\n\n\n\n### multiple\n\nThe `multiple` attribute of the input tag\nWhether to allow multiple files to be selected\n\n* **Type:** `Boolean`\n\n* **Default:** `false`\n\n* **Details:**\n\n If it is `false` file inside only one file will be automatically deleted\n\n* **Usage:**\n ```html\n <file-upload :multiple="true"></file-upload>\n ```\n\n\n\n### directory\n\nThe `directory` attribute of the input tag\nWhether it is a upload folder\n\n* **Type:** `Boolean`\n\n* **Default:** `false`\n\n* **Browser:** [http://caniuse.com/#feat=input-file-directory](http://caniuse.com/#feat=input-file-directory)\n\n* **Usage:**\n ```html\n <file-upload :directory="true" :multiple="true"></file-upload>\n ```\n\n\n\n\n\n### extensions\n\nAllow upload file extensions\n\n* **Type:** `Array | String | RegExp`\n\n* **Default:** `undefined`\n\n* **Usage:**\n ```html\n <file-upload extensions="jpg,gif,png,webp"></file-upload>\n \x3c!--or--\x3e\n <file-upload :extensions="[\'jpg\', \'gif\', \'png\', \'webp\']"></file-upload>\n \x3c!--or--\x3e\n <file-upload :extensions="/\\.(gif|jpe?g|png|webp)$/i"></file-upload>\n ```\n\n\n\n\n### size\n\nAllow the maximum byte to upload\n\n* **Type:** `Number`\n\n* **Default:** `0`\n\n* **Browser:** `> IE9`\n\n* **Details:**\n\n `0` is equal to not limit\n\n* **Usage:**\n ```html\n <file-upload :size="1024 * 1024"></file-upload>\n ```\n\n\n\n\n### timeout\n\nUpload timeout time in milliseconds\n\n* **Type:** `Number`\n\n* **Default:** `0`\n\n* **Browser:** `> IE9`\n\n* **Usage:**\n ```html\n <file-upload :timeout="600 * 1000"></file-upload>\n ```\n\n### maximum\n\nList the maximum number of files\n\n* **Type:** `Number`\n\n* **Default:** `props.multiple ? 0 : 1`\n\n* **Usage:**\n ```html\n <file-upload :maximum="10"></file-upload>\n ```\n\n\n\n### thread\n\nAlso upload the number of files at the same time (number of threads)\n\n* **Type:** `Number`\n\n* **Default:** `1`\n\n* **Browser:** `> IE9`\n\n* **Usage:**\n ```html\n <file-upload :thread="3"></file-upload>\n ```\n\n### chunk-enabled\n\nWhether chunk uploads is enabled or not\n\n* **Type:** `Boolean`\n\n* **Default:** `false`\n\n* **Usage:**\n ```html\n <file-upload :chunk-enabled="true"></file-upload>\n <file-upload chunk-enabled></file-upload>\n ```\n\n### chunk\n\nAll the options to handle chunk uploads\n\n* **Type:** `Object`\n\n* **Default:**\n```js\n{\n headers: {\n \'Content-Type\': \'application/json\'\n },\n action: \'\',\n minSize: 1048576,\n maxActive: 3,\n maxRetries: 5,\n\n // This is the default Handler implemented in this package\n // you can use your own handler if your protocol is different\n handler: ChunkUploadDefaultHandler\n}\n```\n\n### drop\n\nDrag and drop upload\n\n* **Type:** `Boolean | Element | CSS selector`\n\n* **Default:** `false`\n\n* **Browser:** [http://caniuse.com/#feat=dragndrop](http://caniuse.com/#feat=dragndrop)\n\n* **Details:**\n\n If set to `true`, read the parent component as a container\n\n* **Usage:**\n ```html\n <file-upload :drop="true"></file-upload>\n ```\n\n\n\n\n\n### drop-directory\n\nWhether to open the drag directory\n\n* **Type:** `Boolean`\n\n* **Default:** `true`\n\n* **Details:**\n\n If set to `false` filter out the directory\n\n* **Usage:**\n ```html\n <file-upload :drop-directory="false"></file-upload>\n ```\n\n\n\n### add-index\n\n* **Type:** `Boolean, Number`\n\n* **Default:** `undefined`\n\n* **Version:** : `>=2.6.1`\n\n* **Details:**\n\n The default value of the `index` parameter for the [`add()`](#instance-methods-add) method\n\n* **Usage:**\n ```html\n <file-upload :add-index="true"></file-upload>\n ```\n\n\n\n\n## Options / Events\n\nThe files is changed to trigger the method\nDefault for `v-model` binding\n\n### @input\n* **Arguments:**\n\n * `files: Array<File | Object>`\n\n\n* **Usage:**\n ```html\n <template>\n <file-upload :value="files" @input="updatetValue"></file-upload>\n \x3c!--or--\x3e\n <file-upload v-model="files"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n updatetValue(value) {\n this.files = value\n }\n }\n }\n <\/script>\n ```\n\n\n\n### @input-filter\n\nAdd, update, remove pre-filter\n\n* **Arguments:**\n\n * `newFile: File | Object | undefined` `Read and write`\n * `oldFile: File | Object | undefined` `Read only`\n * `prevent: Function` Call this function to prevent modification\n\n\n* **Details:**\n\n If the `newFile` value is `undefined` \'is deleted\n If the `oldFile` value is `undefined` \'is added\n If `newFile`, `oldFile` is exist, it is updated\n\n > Synchronization modify `newFile`\n > Asynchronous Please use `update`,` add`, `remove`,` clear` method\n > Asynchronous Please set an error first to prevent being uploaded\n\n > Synchronization can not use `update`,` add`, `remove`,` clear` methods\n > Asynchronous can not modify `newFile`\n\n* **Usage:**\n ```html\n <template>\n <ul>\n <li v-for="file in files">\n <img :src="file.blob" width="50" height="50" />\n </li>\n </ul>\n <file-upload :value="files" @input-filter="inputFilter"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n inputFilter(newFile, oldFile, prevent) {\n if (newFile && !oldFile) {\n // Add file\n\n // Filter non-image file\n // Will not be added to files\n if (!/\\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(newFile.name)) {\n return prevent()\n }\n\n // Create the \'blob\' field for thumbnail preview\n newFile.blob = \'\'\n let URL = window.URL || window.webkitURL\n if (URL && URL.createObjectURL) {\n newFile.blob = URL.createObjectURL(newFile.file)\n }\n }\n\n if (newFile && oldFile) {\n // Update file\n\n // Increase the version number\n if (!newFile.version) {\n newFile.version = 0\n }\n newFile.version++\n }\n\n if (!newFile && oldFile) {\n // Remove file\n\n // Refused to remove the file\n // return prevent()\n }\n }\n }\n }\n <\/script>\n ```\n\n### @input-file\n\nAdd, update, remove after\n\n* **Arguments:**\n\n * `newFile: File | Object | undefined` `Read only`\n * `oldFile: File | Object | undefined` `Read only`\n\n\n* **Details:**\n\n If the `newFile` value is `undefined` \'is deleted\n If the `oldFile` value is `undefined` \'is added\n If `newFile`, `oldFile` is exist, it is updated\n\n\n >You can use `update`,` add`, `remove`,` clear` methods in the event\n >You can not modify the `newFile` object in the event\n >You can not modify the `oldFile` object in the event\n\n* **Usage:**\n ```html\n <template>\n <file-upload ref="upload" v-model="files" @input-file="inputFile"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n inputFile(newFile, oldFile) {\n if (newFile && !oldFile) {\n // Add file\n }\n\n if (newFile && oldFile) {\n // Update file\n\n // Start upload\n if (newFile.active !== oldFile.active) {\n console.log(\'Start upload\', newFile.active, newFile)\n\n // min size\n if (newFile.size >= 0 && newFile.size < 100 * 1024) {\n newFile = this.$refs.upload.update(newFile, {error: \'size\'})\n }\n }\n\n // Upload progress\n if (newFile.progress !== oldFile.progress) {\n console.log(\'progress\', newFile.progress, newFile)\n }\n\n // Upload error\n if (newFile.error !== oldFile.error) {\n console.log(\'error\', newFile.error, newFile)\n }\n\n // Uploaded successfully\n if (newFile.success !== oldFile.success) {\n console.log(\'success\', newFile.success, newFile)\n }\n }\n\n if (!newFile && oldFile) {\n // Remove file\n\n // Automatically delete files on the server\n if (oldFile.success && oldFile.response.id) {\n // $.ajax({\n // type: \'DELETE\',\n // url: \'/file/delete?id=\' + oldFile.response.id,\n // });\n }\n }\n\n // Automatic upload\n if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) {\n if (!this.$refs.upload.active) {\n this.$refs.upload.active = true\n }\n }\n }\n }\n }\n <\/script>\n ```\n\n\n\n## Instance / Data\n\n### features\n\nUsed to determine the browser support features\n\n* **Type:** `Object`\n\n* **Read only:** `true`\n\n* **Default:** `{ html5: true, directory: false, drop: false }`\n\n* **Usage:**\n ```html\n <app>\n <file-upload ref="upload"></file-upload>\n <span v-show="$refs.upload && $refs.upload.features.drop">Support drag and drop upload</span>\n <span v-show="$refs.upload && $refs.upload.features.directory">Support folder upload</span>\n <span v-show="$refs.upload && $refs.upload.features.html5">Support for HTML5</span>\n </app>\n ```\n\n\n\n### active\n\nActivation or abort upload\n\n* **Type:** `Boolean`\n\n* **Read only:** `false`\n\n* **Default:** `false`\n\n* **Usage:**\n ```html\n <app>\n <file-upload ref="upload"></file-upload>\n <span v-if="!$refs.upload || !$refs.upload.active" @click="$refs.upload.active = true">Start upload</span>\n <span v-else @click="$refs.upload.active = false">Stop upload</span>\n </app>\n ```\n\n\n\n### dropActive\n\nIs dragging\n\n* **Type:** `Boolean`\n\n* **Read only:** `true`\n\n* **Default:** `false`\n\n* **Usage:**\n ```html\n <app>\n <file-upload ref="upload" :drop="true"></file-upload>\n <span v-show="$refs.upload && $refs.upload.dropActive">Drag and drop here for upload</span>\n </app>\n ```\n\n\n\n\n\n### uploaded\n\nAll uploaded\n\n* **Type:** `Boolean`\n\n* **Read only:** `true`\n\n* **Default:** `true`\n\n* **Usage:**\n ```html\n <app>\n <file-upload ref="upload"></file-upload>\n <span v-show="$refs.upload && $refs.upload.uploaded">All files have been uploaded</span>\n </app>\n ```\n\n\n\n\n\n## Instance / Methods\n\n\n\n### get()\n\nUse `id` to get a file object\n\n* **Arguments:**\n\n * `id: File | Object | String`\n\n\n* **Result:** `File | Object | Boolean` There is a return file, object that otherwise returns `false`\n\n\n\n### add()\n\nAdd one or more files\n\n* **Arguments:**\n\n * `files: Array<File | window.File | Object> | File | window.File | Object` If it is an array of responses will be an array\n * `index: Number | Boolean` = [`props.add-index`](#options-props-add-index) `true = ` Start, `false = ` End, `Number = ` Index\n\n\n* **Result:** `Object | Array<File | Object> | Boolean` The incoming array is returned to the array otherwise the object or `false`\n\n* **Usage:**\n ```html\n <template>\n <ul>\n <li v-for="file in files">\n <span>{{file.name}}</span>\n </li>\n </ul>\n <file-upload v-model="files"></file-upload>\n <button type="button" @click.prevent="addText">Add a file</button>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n addText() {\n let file = new window.File([\'foo\'], \'foo.txt\', {\n type: "text/plain",\n })\n this.$refs.upload.add(file)\n }\n }\n }\n <\/script>\n ```\n\n\n### addInputFile()\n\nAdd the file selected by `<input type = "file">` to the upload list\n\n* **Arguments:**\n\n * `el: HTMLInputElement` File element\n\n\n* **Result:** `Array<File>` Added list of files\n\n* **Version:** : `>=2.5.1`\n\n\n\n### addDataTransfer()\n\nAdd files that are dragged or pasted into the upload list\n\n* **Arguments:**\n\n * `dataTransfer: DataTransfer` Drag or paste data\n\n\n* **Result:** `Promise<Array<File>>` Added list of files\n\n\n* **Version:** : `>=2.5.1`\n\n\n\n### update()\n\nUpdate a file object\n\n* **Arguments:**\n\n * `id: File | Object | String`\n * `data: Object` Updated data object\n\n\n* **Result:** `Object | Boolean` Successfully returned `newFile` failed to return` false`\n\n\n* **Usage:**\n ```html\n <template>\n <ul>\n <li v-for="file in files">\n <span>{{file.name}}</span>\n <button v-show="file.active" type="button" @click.prevent="abort(file)">Abort</button>\n </li>\n </ul>\n <file-upload v-model="files"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n abort(file) {\n this.$refs.upload.update(file, {active: false})\n // or\n // this.$refs.upload.update(file, {error: \'abort\'})\n }\n }\n }\n <\/script>\n ```\n\n### remove()\n\nRemove a file object\n\n* **Arguments:**\n\n * `id: File | Object | String`\n\n\n* **Result:** `Object | Boolean` Successfully returned `oldFile` failed to return` false`\n\n* **Usage:**\n ```html\n <template>\n <ul>\n <li v-for="file in files">\n <span>{{file.name}}</span>\n <button type="button" @click.prevent="remove(file)">Remove</button>\n </li>\n </ul>\n <file-upload v-model="files"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n remove(file) {\n this.$refs.upload.remove(file)\n }\n }\n }\n <\/script>\n ```\n\n### replace()\n Replace the location of the two files\n\n* **Arguments:**\n\n * `id1: File | Object | String`\n * `id2: File | Object | String`\n\n\n* **Result:** `Boolean`\n\n\n### clear()\n\nEmpty the file list\n\n* **Result:** `Boolean` Always return `true`\n\n\n\n## Instance / File\n\n\n\n> **File object in the `@input-filter` event outside the use of [`update`](#instance-methods-update) method**\n\n\n\n\n### fileObject\n\n* **Type:** `Boolean`\n\n* **Read only:** `true`\n\n* **Required:** `true`\n\n* **Default:** `true`\n\n* **Version:** : `>=2.6.0`\n\n* **Details:**\n\n If the attribute does not exist, the object will not be processed internally\n If the attribute does not exist, it is not `File` but `Object`\n\n\n\n\n### id\n\nFile ID\n\n* **Type:** `String | Number`\n\n* **Read only:** `false`\n\n* **Default:** `Math.random().toString(36).substr(2)`\n\n* **Details:**\n\n >`id` can not be repeated\n >Upload can not modify `id`\n\n\n### size\n\nFile size\n\n* **Type:** `Number`\n\n* **Read only:** `false`\n\n* **Default:** `-1`\n\n* **Browser:** `> IE9`\n\n\n### name\n\nFilename\n\n* **Type:** `String`\n\n* **Read only:** `false`\n\n* **Default:** ` `\n\n* **Details:**\n\n Format: `directory/filename.gif` `filename.gif`\n\n\n\n### type\n\nMIME type\n\n* **Type:** `String`\n\n* **Read only:** `false`\n\n* **Default:** ` `\n\n* **Browser:** `> IE9`\n\n* **Details:**\n\n Format: `image/gif` `image/png` `text/html`\n\n\n\n\n### active\n\nActivation or abort upload\n\n* **Type:** `Boolean`\n\n* **Read only:** `false`\n\n* **Default:** `false`\n\n* **Details:**\n\n `true` = Upload\n `false` = Abort\n\n\n\n\n\n\n### error\n\nUpload failed error code\n\n* **Type:** `String`\n\n* **Read only:** `false`\n\n* **Default:** ` `\n\n* **Details:**\n\n Built-in\n `size`, `extension`, `timeout`, `abort`, `network`, `server`, `denied`\n\n\n\n\n### success\n\nWhether the upload was successful\n\n* **Type:** `Boolean`\n\n* **Read only:** `false`\n\n* **Default:** `false`\n\n\n### putAction\n\nCustomize the current file `PUT` URL\n\n* **Type:** `String`\n\n* **Read only:** `false`\n\n* **Default:** `this.putAction`\n\n\n\n### postAction\n\nCustomize the current file `POST` URL\n\n* **Type:** `String`\n\n* **Read only:** `false`\n\n* **Default:** `this.postAction`\n\n\n\n\n### headers\n\nCustomize the current file `HTTP` Header\n\n* **Type:** `Object`\n\n* **Read only:** `false`\n\n* **Default:** `this.headers`\n\n\n### data\n\nCustomize the current file `body` or` query` to attach content\n\n* **Type:** `Object`\n\n* **Read only:** `false`\n\n* **Default:** `this.data`\n\n\n### timeout\n\nCustomize the upload timeout for a current single file\n\n* **Type:** `Number`\n\n* **Read only:** `false`\n\n* **Default:** `this.timeout`\n\n\n### response\n\nResponse data\n\n* **Type:** `Object | String`\n\n* **Read only:** `false`\n\n* **Default:** `{}`\n\n\n\n\n### progress\n\nUpload progress\n\n* **Type:** `String`\n\n* **Read only:** `false`\n\n* **Default:** `0.00`\n\n* **Browser:** `> IE9`\n\n\n\n### speed\n\nPer second upload speed\n\n* **Type:** `Number`\n\n* **Read only:** `true`\n\n* **Default:** `0`\n\n* **Browser:** `> IE9`\n\n\n\n\n### xhr\n\n`HTML5` upload` XMLHttpRequest` object\n\n* **Type:** `XMLHttpRequest`\n\n* **Read only:** `true`\n\n* **Default:** `undefined`\n\n* **Browser:** `> IE9`\n\n\n\n\n### iframe\n\n`HTML4` upload` iframe` element\n\n* **Type:** `Element`\n\n* **Read only:** `true`\n\n* **Default:** `undefined`\n\n* **Browser:** `= IE9`\n'},function(e,n){e.exports='## 入门开始\n\n### NPM\n\n``` bash\nnpm install vue-upload-component --save\n```\n\n``` js\nconst VueUploadComponent = require(\'vue-upload-component\')\nVue.component(\'file-upload\', VueUploadComponent)\n```\n\n### Curated\n\n**No data**\n\n\n### 直接使用\n\n\nunpkg\n\n``` html\n<script src="https://unpkg.com/vue"><\/script>\n<script src="https://unpkg.com/vue-upload-component"><\/script>\n<script>\nVue.component(\'file-upload\', VueUploadComponent)\n<\/script>\n```\n\njsDelivr\n\n``` html\n<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"><\/script>\n<script src="https://cdn.jsdelivr.net/npm/vue-upload-component"><\/script>\n<script>\nVue.component(\'file-upload\', VueUploadComponent)\n<\/script>\n```\n\n\n### 简单的例子\n\n\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <title>Vue-upload-component Test</title>\n <script src="https://unpkg.com/vue"><\/script>\n <script src="https://unpkg.com/vue-upload-component"><\/script>\n</head>\n<body>\n<div id="app">\n <ul>\n <li v-for="file in files">{{file.name}} - Error: {{file.error}}, Success: {{file.success}}</li>\n </ul>\n <file-upload\n ref="upload"\n v-model="files"\n post-action="/post.method"\n put-action="/put.method"\n @input-file="inputFile"\n @input-filter="inputFilter"\n >\n 上传文件\n </file-upload>\n <button v-show="!$refs.upload || !$refs.upload.active" @click.prevent="$refs.upload.active = true" type="button">开始上传</button>\n <button v-show="$refs.upload && $refs.upload.active" @click.prevent="$refs.upload.active = false" type="button">停止上传</button>\n</div>\n<script>\nnew Vue({\n el: \'#app\',\n data: function () {\n return {\n files: []\n }\n },\n components: {\n FileUpload: VueUploadComponent\n },\n methods: {\n /**\n * Has changed\n * @param Object|undefined newFile 只读\n * @param Object|undefined oldFile 只读\n * @return undefined\n */\n inputFile: function (newFile, oldFile) {\n if (newFile && oldFile && !newFile.active && oldFile.active) {\n // 获得相应数据\n console.log(\'response\', newFile.response)\n if (newFile.xhr) {\n // 获得响应状态码\n console.log(\'status\', newFile.xhr.status)\n }\n }\n },\n /**\n * Pretreatment\n * @param Object|undefined newFile 读写\n * @param Object|undefined oldFile 只读\n * @param Function prevent 阻止回调\n * @return undefined\n */\n inputFilter: function (newFile, oldFile, prevent) {\n if (newFile && !oldFile) {\n // 过滤不是图片后缀的文件\n if (!/\\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(newFile.name)) {\n return prevent()\n }\n }\n\n // 创建 blob 字段 用于图片预览\n newFile.blob = \'\'\n let URL = window.URL || window.webkitURL\n if (URL && URL.createObjectURL) {\n newFile.blob = URL.createObjectURL(newFile.file)\n }\n }\n }\n});\n<\/script>\n</body>\n</html>\n```\n\n\n\n### SSR (服务器同构)\n\n\n```html\n<template>\n <file-upload v-model="files" post-action="/">Upload file</file-upload>\n</template>\n<style>\n/*\nimport \'~vue-upload-component/dist/vue-upload-component.part.css\'\n@import "~vue-upload-component/dist/vue-upload-component.part.css";\n\n或\n\n\n */\n.file-uploads {\n overflow: hidden;\n position: relative;\n text-align: center;\n display: inline-block;\n}\n.file-uploads.file-uploads-html4 input[type="file"] {\n opacity: 0;\n font-size: 20em;\n z-index: 1;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n position: absolute;\n width: 100%;\n height: 100%;\n}\n.file-uploads.file-uploads-html5 input[type="file"] {\n overflow: hidden;\n position: fixed;\n width: 1px;\n height: 1px;\n z-index: -1;\n opacity: 0;\n}\n</style>\n<script>\nimport FileUpload from \'vue-upload-component/dist/vue-upload-component.part.js\'\nexport default {\n components: {\n FileUpload,\n },\n data() {\n return {\n files: []\n }\n },\n}\n<\/script>\n```\n\n\n** 或者 **\n\n\n```js\nimport FileUpload from \'vue-upload-component/src\'\n```\n\nwebpack.config.js\n\n```js\nconst nodeExternals = require(\'webpack-node-externals\');\n{\n //...\n externals: [\n nodeExternals({whitelist:[/^vue-upload-component\\/src/]})\n ]\n //...\n}\n```\n\n* [https://github.com/liady/webpack-node-externals](https://github.com/liady/webpack-node-externals) \n\n* [**`vue-hackernews` 演示**](https://github.com/lian-yue/vue-hackernews-2.0/) \n\n* [**浏览修改文件**](https://github.com/lian-yue/vue-hackernews-2.0/commit/bd6c58a30cc6b8ba6c0148e737b3ce9336b99cf8)\n\n\n\n\n## 选项 / 属性\n\n\n### input-id\n\ninput 标签的 `id` 属性\n\n* **类型:** `String`\n\n* **默认值:** `this.name`\n\n* **示例:**\n ```html\n <file-upload input-id="file2"></file-upload>\n \x3c!--输出--\x3e\n <input id="file2" />\n ```\n\n\n\n\n\n### name\n\ninput标签的 `name` 属性\n\n* **类型:** `String`\n\n* **默认值:** `file`\n\n* **示例:**\n ```html\n <file-upload name="file"></file-upload>\n \x3c!--输出--\x3e\n <input name="file" />\n ```\n\n\n\n\n\n### post-action\n\n`POST` 请求的上传URL\n\n* **类型:** `String`\n\n* **默认值:** `undefined`\n\n* **示例:**\n ```html\n <file-upload post-action="/upload/post.php"></file-upload>\n ```\n\n\n\n\n\n### put-action\n\n`PUT` 请求的上传URL\n\n* **类型:** `String`\n\n* **默认值:** `undefined`\n\n* **浏览器:** `> IE9`\n\n* **详细:** \n\n `put-action` 不为空请优先 `PUT` 请求 \n\n* **示例:**\n ```html\n <file-upload put-action="/upload/put.php"></file-upload>\n ```\n\n\n\n### custom-action\n\n自定义上传方法\n\n* **类型:** `async Function`\n\n* **默认值:** `undefined`\n\n* **详细:** \n\n `custom-action` 优先级高于 `put-action, post-action`\n\n* **示例:**\n ```html\n <file-upload :custom-action="customAction"></file-upload>\n ```\n ```js\n async function customAction(file, component) {\n // return await component.uploadPut(file)\n return await component.uploadHtml4(file)\n }\n ```\n\n\n\n### headers\n\n自定义上传请求 `header` 数据\n\n* **类型:** `Object`\n\n* **默认值:** `{}`\n\n* **浏览器:** `> IE9`\n\n* **示例:**\n ```html\n <file-upload :headers="{\'X-Token-CSRF\': \'code\'}"></file-upload>\n ```\n\n\n\n\n\n### data\n\n`POST 请求`: 附加请求的 body \n`PUT 请求`: 附加请求的 query \n\n* **类型:** `Object`\n\n* **默认值:** `{}`\n\n* **示例:**\n ```html\n <file-upload :data="{access_token: \'access_token\'}"></file-upload>\n ```\n\n\n\n\n### value, v-model\n\n文件列表\n\n* **类型:** `Array<File | Object>`\n\n* **默认值:** `[]`\n\n* **详细:** \n\n 浏览 **[`File`](#file)** 详细信息 \n > 为了防止不可预知的错误,不可直接修改 `files`,请使用 [`add`](#实例-方法-add), [`update`](#实例-方法-update), [`remove`](#实例-方法-remove) 方法修改\n\n* **示例:**\n ```html\n <file-upload :value="files" @input="updatetValue"></file-upload>\n \x3c!--或--\x3e\n <file-upload v-model="files"></file-upload>\n ```\n\n\n\n\n\n### accept\n\n表单的`accept`属性, MIME type \n\n* **类型:** `String`\n\n* **默认值:** `undefined`\n\n* **浏览器:** `> IE9`\n\n* **示例:**\n ```html\n <file-upload accept="image/png,image/gif,image/jpeg,image/webp"></file-upload>\n \x3c!--或--\x3e\n <file-upload accept="image/*"></file-upload>\n ```\n\n\n\n\n\n### multiple\n\n文件表单的 `multiple` 属性 \n是否允许选择多个文件 \n\n* **类型:** `Boolean`\n\n* **默认值:** `false`\n\n* **详细:** \n\n 如果是 `false` `files` 里面最多只有一个文件 多的会自动删除 \n\n* **示例:**\n ```html\n <file-upload :multiple="true"></file-upload>\n ```\n\n\n\n### directory\n\n文件表单的 `directory` 属性 \n是否是上传文件夹 \n\n* **类型:** `Boolean`\n\n* **默认值:** `false`\n\n* **浏览器:** [http://caniuse.com/#feat=input-file-directory](http://caniuse.com/#feat=input-file-directory)\n\n* **示例:**\n ```html\n <file-upload :directory="true" :multiple="true"></file-upload>\n ```\n\n\n\n\n\n### extensions\n\n允许上传的文件后缀\n\n* **类型:** `Array | String | RegExp`\n\n* **默认值:** `undefined`\n\n* **示例:**\n ```html\n <file-upload extensions="jpg,gif,png,webp"></file-upload>\n \x3c!--或--\x3e\n <file-upload :extensions="[\'jpg\', \'gif\', \'png\', \'webp\']"></file-upload>\n \x3c!--或--\x3e\n <file-upload :extensions="/\\.(gif|jpe?g|png|webp)$/i"></file-upload>\n ```\n\n\n\n\n### size\n\n允许上传的最大字节\n\n* **类型:** `Number`\n\n* **默认值:** `0`\n\n* **浏览器:** `> IE9`\n\n* **详细:**\n\n `0` 等于不限制\n\n* **示例:**\n ```html\n <file-upload :size="1024 * 1024"></file-upload>\n ```\n\n\n\n\n### timeout\n\n上传超时时间毫秒\n\n* **类型:** `Number`\n\n* **默认值:** `0`\n\n* **浏览器:** `> IE9`\n\n* **示例:**\n ```html\n <file-upload :timeout="600 * 1000"></file-upload>\n ```\n\n\n### maximum\n\n列表最大文件数\n\n* **类型:** `Number`\n\n* **默认值:** `props.multiple ? 0 : 1`\n\n* **示例:**\n ```html\n <file-upload :maximum="10"></file-upload>\n ```\n\n\n\n\n### thread\n\n同时并发上传的文件数量 线程数 \n\n* **类型:** `Number`\n\n* **默认值:** `1`\n\n* **浏览器:** `> IE9`\n\n* **示例:**\n ```html\n <file-upload :thread="3"></file-upload>\n ```\n\n\n\n\n\n### drop\n\n拖拽上传 \n\n* **类型:** `Boolean | Element | CSS selector`\n\n* **默认值:** `false`\n\n* **浏览器:** [http://caniuse.com/#feat=dragndrop](http://caniuse.com/#feat=dragndrop)\n\n* **详细:**\n\n 如果设置成 `true` 则读取父组件作为容器 \n\n* **示例:**\n ```html\n <file-upload :drop="true"></file-upload>\n ```\n\n\n\n\n\n### drop-directory\n\n是否开启拖拽目录 \n\n* **类型:** `Boolean`\n\n* **默认值:** `true`\n\n* **详细:**\n\n 如果设置成 `false` 则过滤掉目录\n\n* **示例:**\n ```html\n <file-upload :drop-directory="false"></file-upload>\n ```\n\n\n### add-index\n\n* **类型:** `Boolean, Number`\n\n* **默认值:** `undefined`\n\n* **版本:** `>= 2.6.1`\n\n* **详细:**\n\n [`add()`](#实例-方法-add) 方法 `index` 参数的默认值\n\n* **示例:**\n ```html\n <file-upload :add-index="true"></file-upload>\n ```\n\n\n\n## 选项 / 事件\n\n文件被改变触发的方法 \n默认用于`v-model`绑定\n\n### @input\n* **参数:**\n\n * `files: Array<File | Object>`\n\n\n* **示例:**\n ```html\n <template>\n <file-upload :value="files" @input="updatetValue"></file-upload>\n \x3c!--或者--\x3e\n <file-upload v-model="files"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n updatetValue(value) {\n this.files = value\n }\n }\n }\n <\/script>\n ```\n\n\n\n### @input-filter\n\nAdd, update, remove pre-filter \n\n* **参数:**\n\n * `newFile: File | Object | undefined` `读写`\n * `oldFile: File | Object | undefined` `只读`\n * `prevent: Function` 调用该方法 阻止修改\n\n\n* **详细:**\n\n 如果 `newFile` 值为 `undefined` 则是删除 \n 如果 `oldFile` 值为 `undefined` 则是添加 \n 如果 `newFile`, `oldFile` 都存在则是更新\n\n > 事件内同步处理请直接修改 `newFile` \n > 事件内异步处理请使用 `update`, `add`, `remove`, `clear` 方法 \n > 异步请先设置一个错误以防止被上传\n\n > 同步不能使用 `update`, `add`, `remove`, `clear` 方法 \n > 异步不能修改 `newFile`\n\n\n* **示例:** \n ```html\n <template>\n <ul>\n <li v-for="file in files">\n <img :src="file.blob" width="50" height="50" />\n </li>\n </ul>\n <file-upload :value="files" @input-filter="inputFilter"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n inputFilter(newFile, oldFile, prevent) {\n if (newFile && !oldFile) {\n // 添加文件\n\n // 过滤非图片文件\n // 不会添加到 files 去\n if (!/\\.(jpeg|jpe|jpg|gif|png|webp)$/i.test(newFile.name)) {\n return prevent()\n }\n\n // 创建 `blob` 字段 用于缩略图预览\n newFile.blob = \'\'\n let URL = window.URL || window.webkitURL\n if (URL && URL.createObjectURL) {\n newFile.blob = URL.createObjectURL(newFile.file)\n }\n }\n\n if (newFile && oldFile) {\n // 更新文件\n\n // 增加版本号\n if (!newFile.version) {\n newFile.version = 0\n }\n newFile.version++\n }\n\n if (!newFile && oldFile) {\n // 移除文件\n\n // 拒绝删除文件\n // return prevent()\n }\n }\n }\n }\n <\/script>\n ```\n\n### @input-file\n\n添加,更新,移除 后\n\n* **参数:**\n\n * `newFile: File | Object | undefined` `只读`\n * `oldFile: File | Object | undefined` `只读`\n\n\n* **详细:**\n\n 如果 `newFile` 值为 `undefined` 则是删除 \n 如果 `oldFile` 值为 `undefined` 则是添加 \n 如果 `newFile`, `oldFile` 都存在则是更新\n\n >事件内可使用 `update`, `add`, `remove`, `clear` 方法 \n >事件内不可修改 `newFile` 对象 \n >事件内不可修改 `oldFile` 对象\n\n* **示例:**\n ```html\n <template>\n <file-upload ref="upload" v-model="files" @input-file="inputFile"></file-upload>\n </template>\n <script>\n export default {\n data() {\n return {\n files: []\n }\n },\n methods: {\n inputFile(newFile, oldFile) {\n if (newFile && !oldFile) {\n // 添加文件\n }\n\n if (newFile && oldFile) {\n // 更新文件\n\n // 开始上传\n if (newFile.active !== oldFile.active) {\n console.log(\'Start upload\', newFile.active, newFile)\n\n // 限定最小字节\n if (newFile.size >= 0 && newFile.size < 100 * 1024) {\n newFile = this.$refs.upload.update(newFile, {error: \'size\'})\n }\n }\n\n // 上传进度\n if (newFile.progress !== oldFile.progress) {\n console.log(\'progress\', newFile.progress, newFile)\n }\n\n // 上传错误\n if (newFile.error !== oldFile.error) {\n console.log(\'error\', newFile.error, newFile)\n }\n\n // 上传成功\n if (newFile.success !== oldFile.success) {\n console.log(\'success\', newFile.success, newFile)\n }\n }\n\n if (!newFile && oldFile) {\n // 删除文件\n\n // 自动删除 服务器上的文件\n if (oldFile.success && oldFile.response.id) {\n // $.ajax({\n // type: \'DELETE\',\n // url: \'/file/delete?id=\' + oldFile.response.id,\n // });\n }\n }\n\n // 自动上传\n if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) {\n if (!this.$refs.upload.active) {\n this.$refs.upload.active = true\n }\n }\n }\n }\n }\n <\/script>\n ```\n\n\n\n## 实例 / 数据\n\n### features\n\n用于判断浏览器支持的特性\n\n* **类型:** `Object`\n\n* **只读:** `true`\n\n* **默认值:** `{ html5: true, directory: false, drop: false }`\n\n* **示例:**\n ```html\n <app>\n <file-upload ref="upload"></file-uplo