Add example

master
git 9 years ago
parent e4705d3820
commit b782af2df7

@ -37,10 +37,13 @@
``` ```
## Example ## Examples
https://lian-yue.github.io/vue-upload-component/ https://lian-yue.github.io/vue-upload-component/
https://github.com/lian-yue/vue-upload-component/tree/2.0/examples/
``` html ``` html
<!-- Example file ./index.html --> <!-- Example file ./index.html -->
<!-- Example file ./src/example.js --> <!-- Example file ./src/example.js -->
@ -54,7 +57,7 @@ https://lian-yue.github.io/vue-upload-component/
new Vue({ new Vue({
el:'#app', el:'#app',
components: { components: {
FileUpload:FileUpload, FileUpload: FileUpload,
}, },
}); });
</script> </script>
@ -188,5 +191,15 @@ npm run build
uploaded: true, // Read only uploaded: true, // Read only
dropActive: false, // Read only dropActive: false, // Read only
destroy: false, // Read only Component destroy = true
} }
``` ```
## methods
````
clear() // Clear all files
remove(id or file Object) // Remove a file return file object or false
abort(id or file Object) // Stop a file upload return file object or false
```

20870
dist/example.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -634,14 +634,14 @@ return /******/ (function(modules) { // webpackBootstrap
var _stringify2 = _interopRequireDefault(_stringify); var _stringify2 = _interopRequireDefault(_stringify);
var _typeof2 = __webpack_require__(47);
var _typeof3 = _interopRequireDefault(_typeof2);
var _assign = __webpack_require__(42); var _assign = __webpack_require__(42);
var _assign2 = _interopRequireDefault(_assign); var _assign2 = _interopRequireDefault(_assign);
var _typeof2 = __webpack_require__(47);
var _typeof3 = _interopRequireDefault(_typeof2);
var _defineProperty2 = __webpack_require__(46); var _defineProperty2 = __webpack_require__(46);
var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _defineProperty3 = _interopRequireDefault(_defineProperty2);
@ -723,6 +723,7 @@ return /******/ (function(modules) { // webpackBootstrap
mode: 'html5', mode: 'html5',
active: false, active: false,
uploaded: true, uploaded: true,
destroy: false,
dropActive: false dropActive: false
}; };
}, },
@ -746,6 +747,7 @@ return /******/ (function(modules) { // webpackBootstrap
}, },
beforeDestroy: function beforeDestroy() { beforeDestroy: function beforeDestroy() {
this.active = false; this.active = false;
this.destroy = true;
this.files.splice(0, this.files.length); this.files.splice(0, this.files.length);
}, },
render: function render(h) { render: function render(h) {
@ -774,20 +776,31 @@ return /******/ (function(modules) { // webpackBootstrap
this._drop(value); this._drop(value);
}, },
files: function files(_files) { files: function files(_files) {
var ids = []; var diffCount = 0;
var fileMaps = {};
for (var i = 0; i < _files.length; i++) { for (var i = 0; i < _files.length; i++) {
var file = _files[i]; var file = _files[i];
if (!file.error && !file.success) { if (!file.error && !file.success) {
this.uploaded = false; this.uploaded = false;
} }
ids.push(file.id);
if (!this._files[file.id]) {
diffCount++;
this._files[file.id] = file;
this._uploadEvents('add', file);
}
fileMaps[file.id] = true;
} }
for (var id in this._files) { for (var id in this._files) {
if (ids.indexOf(id) != -1) { if (fileMaps[id]) {
continue; continue;
} }
var _file = this._files; diffCount++;
var _file = this._files[id];
_file.removed = true; _file.removed = true;
@ -805,7 +818,9 @@ return /******/ (function(modules) { // webpackBootstrap
delete this._files[id]; delete this._files[id];
this._uploadEvents('remove', _file); this._uploadEvents('remove', _file);
} }
this._index = 0; if (diffCount) {
this._index = 0;
}
}, },
active: function active(newValue, oldValue) { active: function active(newValue, oldValue) {
if (newValue && !oldValue) { if (newValue && !oldValue) {
@ -825,6 +840,37 @@ return /******/ (function(modules) { // webpackBootstrap
this.files.splice(0, this.files.length); this.files.splice(0, this.files.length);
} }
}, },
select: function select(file) {
if ((typeof file === 'undefined' ? 'undefined' : (0, _typeof3.default)(file)) == 'object') {
var index = this.files.indexOf(file);
if (index == -1) {
return false;
}
return file;
}
var id = file;
for (var i = 0; i < this.files.length; i++) {
file = this.files[i];
if (file.id == id) {
return file;
}
}
return false;
},
remove: function remove(file) {
file = this.select(file);
if (file) {
this.files.splice(this.files.indexOf(file), 1);
}
return file;
},
abort: function abort(file) {
file = this.select(file);
if (file) {
file.active = false;
}
return file;
},
addFileUpload: function addFileUpload(file) { addFileUpload: function addFileUpload(file) {
this.uploaded = false; this.uploaded = false;
var defaultFile = { var defaultFile = {
@ -835,6 +881,7 @@ return /******/ (function(modules) { // webpackBootstrap
active: false, active: false,
error: '', error: '',
success: false, success: false,
removed: false,
putAction: this.putAction, putAction: this.putAction,
postAction: this.postAction, postAction: this.postAction,
timeout: this.timeout, timeout: this.timeout,
@ -855,10 +902,7 @@ return /******/ (function(modules) { // webpackBootstrap
if (!this.multiple) { if (!this.multiple) {
this.clear(); this.clear();
} }
var index = this.files.push(file);
file = this.files[this.files.push(file) - 1];
this._files[file.id] = file;
this._uploadEvents('add', file);
}, },
_uploadEvents: function _uploadEvents(name, file) { _uploadEvents: function _uploadEvents(name, file) {
this.events && this.events[name] && this.events[name].call(this, file, this); this.events && this.events[name] && this.events[name].call(this, file, this);
@ -2169,7 +2213,7 @@ return /******/ (function(modules) { // webpackBootstrap
// module // module
exports.push([module.id, "\n.file-uploads {\n overflow: hidden;\n position: relative;\n text-align: center;\n}\n.file-uploads span{\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n -o-user-select: none;\n user-select: none;\n}\n.file-uploads input{\n z-index: 1;\n opacity: 0;\n font-size: 20em;\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{\n float: left;\n width: 1px !important;\n height: 1px !important;\n top:-1px !important;\n left:-1px !important;\n right:auto !important;\n bottom:auto !important;\n}\n", ""]); exports.push([module.id, "\n.file-uploads {\n overflow: hidden;\n position: relative;\n text-align: center;\n display: inline-block;\n}\n.file-uploads span{\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n -o-user-select: none;\n user-select: none;\n}\n.file-uploads input{\n z-index: 1;\n opacity: 0;\n font-size: 20em;\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{\n position: fixed;\n width: 1px !important;\n height: 1px !important;\n top: -999em !important;\n left:0 !important;\n right:auto !important;\n bottom:auto !important;\n}\n", ""]);
// exports // exports
@ -2519,8 +2563,8 @@ return /******/ (function(modules) { // webpackBootstrap
if(false) { if(false) {
// When the styles change, update the <style> tags // When the styles change, update the <style> tags
if(!content.locals) { if(!content.locals) {
module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-62f6c1f3!./../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./FileUpload.vue", function() { module.hot.accept("!!./../node_modules/css-loader/index.js!./../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-4563ebb1!./../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./FileUpload.vue", function() {
var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-62f6c1f3!./../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./FileUpload.vue"); var newContent = require("!!./../node_modules/css-loader/index.js!./../node_modules/vue-loader/lib/style-rewriter.js?id=data-v-4563ebb1!./../node_modules/vue-loader/lib/selector.js?type=styles&index=0!./FileUpload.vue");
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']]; if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
update(newContent); update(newContent);
}); });

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,32 @@
<style>
nav {
margin-bottom: 1em
}
</style>
<script>
export default {
render(h) {
return (
<div id="app">
<header id="header">
<h1>Upload test</h1>
<nav>
<h3>Navigation</h3>
<h3>Need to run local <code>`npm run dev`</code></h3>
<ul>
<li><router-link to="/">Home</router-link></li>
<li><router-link to="/multi">Multi components</router-link></li>
<li><router-link to="/cross-router">Cross router</router-link></li>
<li><router-link to="/vuex">Vuex</router-link></li>
</ul>
</nav>
</header>
<router-view id="main"></router-view>
<footer id="footer">
<div>Powered by:<a href="//www.lianyue.org">LianYue</a></div>
</footer>
</div>
)
}
}
</script>

@ -0,0 +1,50 @@
<style>
.cross-router {
margin-top: 2em
}
.cross-router .file-uploads {
font-size: 18px;
padding: .6em;
font-weight: bold;
border: 1px solid #888;
background: #f3f3f3
}
.cross-router button {
padding: .6em;
}
.cross-router .list li {
border-bottom: 1px solid #888;
}
.cross-router .list span {
display: inline-block;
padding: .4em
}
</style>
<template>
<main class="cross-router">
<nav>
<h3>Sub navigation</h3>
<ul>
<li><router-link to="/cross-router">File upload</router-link></li>
<li><router-link to="/cross-router/list">File list</router-link></li>
</ul>
</nav>
<keep-alive>
<router-view :files="files"></router-view>
</keep-alive>
</main>
</template>
<script>
export default {
data() {
return {
files: [],
}
},
}
</script>

@ -0,0 +1,47 @@
<template>
<div>
<h2>List</h2>
<div class="lists">
<table>
<thead>
<tr>
<th>Index</th>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Progress</th>
<th>Speed</th>
<th>Active</th>
<th>Error</th>
<th>Success</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in files">
<td>{{index}}</td>
<td>{{file.id}}</td>
<td>{{file.name}}</td>
<td>{{file.size | formatSize}}</td>
<td>{{file.progress}}</td>
<td>{{file.speed | formatSize}}</td>
<td>{{file.active}}</td>
<td>{{file.error}}</td>
<td>{{file.success}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
props: {
files: {
type: Array,
default: () => [],
},
}
}
</script>

@ -0,0 +1,41 @@
<template>
<div>
<div class="upload-btn">
<file-upload
title="Add upload files"
name="file"
post-action="/post"
put-action="/put"
:multiple="true"
:files="files"
ref="upload">
</file-upload>
<button v-show="!upload.active" @click.prevent="upload.active = true" type="button">Start upload</button>
<button v-show="upload.active" @click.prevent="upload.active = false" type="button">Stop upload</button>
</div>
</div>
</template>
<script>
import FileUpload from '../src'
export default {
components: {
FileUpload,
},
props: {
files: {
type: Array,
default: () => [],
},
},
data() {
return {
upload: {},
}
},
mounted() {
this.upload = this.$refs.upload.$data
}
}
</script>

@ -0,0 +1,228 @@
<style>
.home {
position: relative;
}
.file-uploads {
font-size: 18px;
padding: .6em;
font-weight: bold;
border: 1px solid #888;
background: #f3f3f3
}
.drop-active {
top: 0;
bottom: 0;
right: 0;
left: 0;
position: absolute;
opacity: .4;
background: #000;
}
button {
padding: .6em;
}
table {
margin-bottom: 2em
}
table th,table td {
padding: .4em;
border: 1px solid #ddd
}
</style>
<template>
<main class="home">
<div id="lists">
<table>
<thead>
<tr>
<th>Index</th>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Progress</th>
<th>Speed</th>
<th>Active</th>
<th>Error</th>
<th>Success</th>
<th>Abort</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in files">
<td>{{index}}</td>
<td>{{file.id}}</td>
<td>{{file.name}}</td>
<td>{{file.size | formatSize}}</td>
<td>{{file.progress}}</td>
<td>{{file.speed | formatSize}}</td>
<td>{{file.active}}</td>
<td>{{file.error}}</td>
<td>{{file.success}}</td>
<td><button type="button" @click.prevent="file.active = false">Abort</button></td>
<td><button type="button" @click.prevent="remove(file)">x</button></td>
</tr>
</tbody>
</table>
</div>
<div id="options">
<table>
<tbody>
<tr>
<td>
<file-upload
:title="title"
:events="events"
:name="name"
:post-action="postAction"
:put-action="putAction"
:extensions="extensions"
:accept="accept"
:multiple="multiple"
:size="size || 0"
:headers="headers"
:data="data"
:drop="drop"
:files="files"
ref="upload">
</file-upload>
</td>
<td>
<button v-show="!upload.active" @click.prevent="upload.active = true" type="button">Start upload</button>
<button v-show="upload.active" @click.prevent="upload.active = false" type="button">Stop upload</button>
</td>
<td>
<label>
Auto start: <input type="checkbox" id="checkbox" v-model="auto">
</label>
</td>
<td>
<label>
Accept: <input type="text" v-model="accept">
</label>
</td>
<td>
<label>
Extensions: <input type="text" v-model="extensions">
</label>
</td>
<td>
<label>
Drop: <input type="checkbox" id="checkbox" v-model="drop">
</label>
</td>
<td>
<label>
Max file size: <input type="text" v-model.number="size">
</label>
</td>
<td>
<label>
Multiple: <input type="checkbox" id="checkbox" v-model="multiple">
</label>
</td>
</tr>
<tr>
<td>
Auto start: {{auto}}
</td>
<td>
Active: {{upload.active}}
</td>
<td>
Uploaded: {{upload.uploaded}}
</td>
<td>
Drop active: {{upload.dropActive}}
</td>
</tr>
</tbody>
</table>
</div>
<div v-show="upload.dropActive" class="drop-active">
Drop ing
</div>
</main>
</template>
<script>
import FileUpload from '../src'
export default {
components: {
FileUpload,
},
data() {
return {
accept: 'image/*',
accept: '',
size: 1024 * 1024 * 10,
multiple: true,
extensions: 'gif,jpg,png',
// extensions: ['gif','jpg','png'],
// extensions: /\.(gif|png|jpg)$/i,
files: [],
upload: {},
title: 'Add upload files',
drop: true,
auto: false,
name: 'file',
postAction: './post.php',
putAction: './put.php',
headers: {
"X-Csrf-Token": "xxxx",
},
data: {
"_csrf_token": "xxxxxx",
},
events: {
add(file, component) {
console.log('add');
if (this.$parent.auto) {
component.active = true;
}
file.headers['X-Filename'] = encodeURIComponent(file.name)
file.data.finename = file.name
// file.putAction = 'xxx'
// file.postAction = 'xxx'
},
progress(file, component) {
console.log('progress ' + file.progress);
},
after(file, component) {
console.log('after');
},
before(file, component) {
console.log('before');
},
}
}
},
mounted() {
this.upload = this.$refs.upload.$data
},
methods: {
remove(file) {
var index = this.files.indexOf(file)
if (index != -1) {
this.files.splice(index, 1);
}
},
},
}
</script>

@ -0,0 +1,123 @@
<template>
<main class="multi">
<div class="image">
<div class="lists">
<table>
<thead>
<tr>
<th>Index</th>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Progress</th>
<th>Speed</th>
<th>Active</th>
<th>Error</th>
<th>Success</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in imageFiles">
<td>{{index}}</td>
<td>{{file.id}}</td>
<td>{{file.name}}</td>
<td>{{file.size | formatSize}}</td>
<td>{{file.progress}}</td>
<td>{{file.speed | formatSize}}</td>
<td>{{file.active}}</td>
<td>{{file.error}}</td>
<td>{{file.success}}</td>
</tr>
</tbody>
</table>
</div>
<div class="upload-btn">
<file-upload
title="Add upload images"
name="image"
post-action="/image"
put-action="/image"
accept='image/*'
:multiple="true"
:files="imageFiles"
ref="image">
</file-upload>
<button v-show="!image.active" @click.prevent="image.active = true" type="button">Start upload</button>
</div>
</div>
<div class="video">
<div class="lists">
<table>
<thead>
<tr>
<th>Index</th>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Progress</th>
<th>Speed</th>
<th>Active</th>
<th>Error</th>
<th>Success</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in videoFiles">
<td>{{index}}</td>
<td>{{file.id}}</td>
<td>{{file.name}}</td>
<td>{{file.size | formatSize}}</td>
<td>{{file.progress}}</td>
<td>{{file.speed | formatSize}}</td>
<td>{{file.active}}</td>
<td>{{file.error}}</td>
<td>{{file.success}}</td>
</tr>
</tbody>
</table>
</div>
<div class="upload-btn">
<file-upload
title="Add upload videos"
name="video"
post-action="/video"
put-action="/video"
accept='video/*'
:multiple="true"
:files="videoFiles"
ref="video">
</file-upload>
<button v-show="!video.active" @click.prevent="video.active = true" type="button">Start upload</button>
<button v-show="video.active" @click.prevent="video.active = false" type="button">Stop upload</button>
</div>
</div>
</main>
</template>
<script>
import FileUpload from '../src'
export default {
components: {
FileUpload,
},
data() {
return {
image: {},
imageFiles: [],
video: {},
videoFiles: [],
}
},
mounted() {
this.image = this.$refs.image.$data
this.video = this.$refs.video.$data
},
}
</script>

@ -0,0 +1,110 @@
<template>
<div>
<div class="upload-btn">
<file-upload
title="Add upload files"
name="file"
post-action="/"
:multiple="true"
:events="events"
ref="upload">
</file-upload>
<button v-show="!upload.active" @click.prevent="upload.active = true" type="button">Start upload</button>
<button v-show="upload.active" @click.prevent="upload.active = false" type="button">Stop upload</button>
</div>
<div class="lists">
<table>
<thead>
<tr>
<th>Index</th>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Progress</th>
<th>Speed</th>
<th>Active</th>
<th>Error</th>
<th>Success</th>
<th>Abort</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in files">
<td>{{index}}</td>
<td>{{file.id}}</td>
<td>{{file.name}}</td>
<td>{{file.size | formatSize}}</td>
<td>{{file.progress}}</td>
<td>{{file.speed | formatSize}}</td>
<td>{{file.active}}</td>
<td>{{file.error}}</td>
<td>{{file.success}}</td>
<td><button type="button" @click.prevent="abort(file)">Abort</button></td>
<td><button type="button" @click.prevent="remove(file)">x</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
import FileUpload from '../src'
import { mapState } from 'vuex'
function addFile(file) {
var newFile = Object.assign({}, file)
file._vuex = newFile
this.$store.commit('addFile', newFile)
}
function updateFile(file) {
var oldFile = file._vuex
var newFile = Object.assign({}, file)
file._vuex = newFile
this.$store.commit('updateFile', {oldFile, newFile})
}
function removeFile(file) {
this.$store.commit('removeFile', file._vuex)
}
export default {
components: {
FileUpload,
},
data() {
return {
upload: {},
events: {
add: addFile,
progress: updateFile,
before: updateFile,
after: updateFile,
remove: removeFile,
},
}
},
computed: mapState({
files: state => state.files
}),
methods: {
remove(file) {
this.$store.commit('removeFile', file)
this.$refs.upload.remove(file.id)
},
abort(file) {
this.$refs.upload.abort(file.id)
},
},
mounted() {
this.upload = this.$refs.upload.$data
}
}
</script>

@ -0,0 +1,77 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'
import Home from './Home'
import Multi from './Multi'
import CrossRouter from './CrossRouter'
import CrossRouterUpload from './CrossRouterUpload'
import CrossRouterList from './CrossRouterList'
import VuexComponent from './Vuex'
import store from './store'
Vue.use(VueRouter)
Vue.config.silent = false;
Vue.config.devtools = true;
Vue.filter('formatSize', function(size) {
if (size > 1024 * 1024 * 1024 * 1024) {
return (size / 1024 / 1024 / 1024 / 1024).toFixed(2) + ' TB';
} else if (size > 1024 * 1024 * 1024) {
return (size / 1024 / 1024 / 1024).toFixed(2) + ' GB';
} else if (size > 1024 * 1024) {
return (size / 1024 / 1024).toFixed(2) + ' MB';
} else if (size > 1024) {
return (size / 1024).toFixed(2) + ' KB';
}
return size.toString() + ' B';
});
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{
path: '/',
component: Home
},
{
path: '/multi',
component: Multi
},
{
path: '/cross-router',
component: CrossRouter,
children: [
{ path: '', component: CrossRouterUpload },
{ path: 'list', component: CrossRouterList }
]
},
{
path: '/vuex',
component: VuexComponent,
},
]
})
new Vue({
router,
store,
render(h) {
return h(App)
}
}).$mount('#app')

@ -0,0 +1,46 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
files: [],
}
const mutations = {
addFile (state, file) {
state.files.push(file)
},
updateFile (state, {oldFile, newFile}) {
var index = state.files.indexOf(oldFile)
if (index == -1) {
return
}
state.files.splice(index, 1, newFile);
},
removeFile(state, file) {
var index = state.files.indexOf(file)
if (index != -1) {
state.files.splice(index, 1);
}
},
}
const actions = {
}
const getters = {
}
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production',
state,
getters,
actions,
mutations
})

@ -3,144 +3,10 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>vue-upload-component</title> <title>vue-upload-component</title>
<style type="text/css">
#app {
position: relative;
}
.file-upload {
display: block;
}
.file-upload span{
display: block;
font-size: 18px;
padding: 1em;
font-weight: bold;
border: 1px solid #888;
}
.drop-active {
top: 0;
bottom: 0;
right: 0;
left: 0;
position: absolute;
opacity: .4;
background: #000;
}
</style>
</head> </head>
<body> <body>
<div id="app"> <div id="app"></div>
<table style="width: 100%; border: 1px solid #ddd;"> <script src="/vue-upload-component/dist/example.js"></script>
<thead> <script src="/dist/example.js"></script>
<tr>
<th>Index</th>
<th>ID</th>
<th>Name</th>
<th>Size</th>
<th>Progress</th>
<th>Speed</th>
<th>Active</th>
<th>Error</th>
<th>Success</th>
<th>Abort</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(file, index) in files">
<td>{{index}}</td>
<td>{{file.id}}</td>
<td>{{file.name}}</td>
<td>{{file.size | formatSize}}</td>
<td>{{file.progress}}</td>
<td>{{file.speed | formatSize}}</td>
<td>{{file.active}}</td>
<td>{{file.error}}</td>
<td>{{file.success}}</td>
<td @click="file.active = false">Abort</td>
<td @click="remove(file)">x</td>
</tr>
</tbody>
</table>
<br/>
<br/>
<table style="width: 100%; border: 1px solid #ddd;">
<tbody>
<tr>
<td>
<file-upload
:title="title"
class="file-upload"
:events="events"
:name="name"
:post-action="postAction"
:put-action="putAction"
:extensions="extensions"
:accept="accept"
:multiple="multiple"
:size="size"
:headers="headers"
:data="data"
:drop="drop"
:files="files"
ref="upload">
</file-upload>
</td>
<td>
<button v-if="upload.active" type="submit" @click.prevent="upload.active = !upload.active">Stop upload</button>
<button v-else type="submit" @click.prevent="upload.active = !upload.active">Start upload</button>
</td>
<td>
<label>
Auto start: <input type="checkbox" id="checkbox" v-model="auto">
</label>
</td>
<td>
<label>
Accept: <input type="text" v-model="accept">
</label>
</td>
<td>
<label>
Extensions: <input type="text" v-model="extensions">
</label>
</td>
<td>
<label>
Drop: <input type="checkbox" id="checkbox" v-model="drop">
</label>
</td>
<td>
<label>
Max file size: <input type="text" v-model.number="size">
</label>
</td>
<td>
<label>
Multiple: <input type="checkbox" id="checkbox" v-model="multiple">
</label>
</td>
</tr>
<tr>
<td>
Auto start: {{auto}}
</td>
<td>
Active: {{upload.active}}
</td>
<td>
Uploaded: {{upload.uploaded}}
</td>
<td>
Drop active: {{upload.dropActive}}
</td>
</tr>
</tbody>
</table>
<div v-show="upload.dropActive" class="drop-active">
Drop ing
</div>
</div>
<script src="./dist/example.js"></script>
</body> </body>
</html> </html>

@ -1,7 +1,7 @@
{ {
"name": "vue-upload-component", "name": "vue-upload-component",
"description": "Vue.js file upload component, Support for multiple file uploads, progress, html5, html4, support ie9", "description": "Vue.js file upload component, Support for multiple file uploads, progress, html5, html4, support ie9",
"version": "2.1.0-beta.4", "version": "2.2.0-beta.1",
"author": "LianYue", "author": "LianYue",
"scripts": { "scripts": {
"dev": "webpack-dev-server --inline --hot", "dev": "webpack-dev-server --inline --hot",
@ -33,14 +33,13 @@
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"babel-core": "^6.0.0", "babel-core": "^6.0.0",
"babel-helper-vue-jsx-merge-props": "^2.0.1", "babel-helper-vue-jsx-merge-props": "^2.0.2",
"babel-loader": "^6.0.0", "babel-loader": "^6.0.0",
"babel-plugin-syntax-jsx": "^6.13.0", "babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.0.0", "babel-plugin-transform-runtime": "^6.0.0",
"babel-plugin-transform-vue-jsx": "^3.1.0", "babel-plugin-transform-vue-jsx": "^3.3.0",
"babel-preset-es2015": "^6.0.0", "babel-preset-es2015": "^6.0.0",
"babel-preset-stage-0": "^6.5.0", "babel-preset-stage-0": "^6.5.0",
"babel-preset-stage-2": "^6.0.0",
"babel-runtime": "^6.0.0", "babel-runtime": "^6.0.0",
"cross-env": "^1.0.6", "cross-env": "^1.0.6",
"css-loader": "^0.23.0", "css-loader": "^0.23.0",
@ -48,12 +47,13 @@
"file-loader": "^0.8.4", "file-loader": "^0.8.4",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"url-loader": "^0.5.7", "url-loader": "^0.5.7",
"vue": "^2.1.3", "vue": "^2.2.1",
"vue-hot-reload-api": "^1.2.0", "vue-hot-reload-api": "^1.2.0",
"vue-html-loader": "^1.0.0", "vue-html-loader": "^1.0.0",
"vue-loader": "^9.5.0", "vue-loader": "^9.5.0",
"vue-router": "^2.3.0",
"vue-style-loader": "^1.0.0", "vue-style-loader": "^1.0.0",
"vue-template-compiler": "^2.1.3", "vuex": "^2.2.1",
"webpack": "^1.12.2", "webpack": "^1.12.2",
"webpack-dev-server": "^1.12.0" "webpack-dev-server": "^1.12.0"
} }

@ -3,6 +3,7 @@
overflow: hidden; overflow: hidden;
position: relative; position: relative;
text-align: center; text-align: center;
display: inline-block;
} }
.file-uploads span{ .file-uploads span{
-webkit-user-select: none; -webkit-user-select: none;
@ -24,11 +25,11 @@
height: 100%; height: 100%;
} }
.file-uploads.file-uploads-html5 input{ .file-uploads.file-uploads-html5 input{
float: left; position: fixed;
width: 1px !important; width: 1px !important;
height: 1px !important; height: 1px !important;
top:-1px !important; top: -999em !important;
left:-1px !important; left:0 !important;
right:auto !important; right:auto !important;
bottom:auto !important; bottom:auto !important;
} }
@ -104,6 +105,7 @@ export default {
mode: 'html5', mode: 'html5',
active: false, active: false,
uploaded: true, uploaded: true,
destroy: false,
dropActive: false, dropActive: false,
} }
}, },
@ -129,6 +131,7 @@ export default {
// //
beforeDestroy() { beforeDestroy() {
this.active = false; this.active = false;
this.destroy = true;
this.files.splice(0, this.files.length); this.files.splice(0, this.files.length);
}, },
@ -153,20 +156,35 @@ export default {
this._drop(value); this._drop(value);
}, },
files(files) { files(files) {
var ids = []; var diffCount = 0
var fileMaps = {};
for (var i = 0; i < files.length; i++) { for (var i = 0; i < files.length; i++) {
let file = files[i]; let file = files[i];
//
if (!file.error && !file.success) { if (!file.error && !file.success) {
this.uploaded = false; this.uploaded = false;
} }
ids.push(file.id);
//
if (!this._files[file.id]) {
diffCount++
this._files[file.id] = file
this._uploadEvents('add', file);
}
// maps
fileMaps[file.id] = true
} }
//
for (var id in this._files) { for (var id in this._files) {
if (ids.indexOf(id) != -1) { if (fileMaps[id]) {
continue; continue;
} }
let file = this._files; diffCount++
let file = this._files[id];
// //
file.removed = true; file.removed = true;
@ -188,7 +206,9 @@ export default {
delete this._files[id]; delete this._files[id];
this._uploadEvents('remove', file); this._uploadEvents('remove', file);
} }
this._index = 0; if (diffCount) {
this._index = 0;
}
}, },
active(newValue, oldValue) { active(newValue, oldValue) {
@ -211,6 +231,40 @@ export default {
} }
}, },
select(file) {
if (typeof file == 'object') {
var index = this.files.indexOf(file)
if (index == -1) {
return false
}
return file
}
var id = file
for (var i = 0; i < this.files.length; i++) {
file = this.files[i]
if (file.id == id) {
return file
}
}
return false
},
remove(file) {
file = this.select(file)
if (file) {
this.files.splice(this.files.indexOf(file), 1)
}
return file
},
abort(file) {
file = this.select(file)
if (file) {
file.active = false
}
return file
},
addFileUpload(file) { addFileUpload(file) {
this.uploaded = false; this.uploaded = false;
var defaultFile = { var defaultFile = {
@ -221,6 +275,7 @@ export default {
active: false, active: false,
error: '', error: '',
success: false, success: false,
removed: false,
putAction: this.putAction, putAction: this.putAction,
postAction: this.postAction, postAction: this.postAction,
timeout: this.timeout, timeout: this.timeout,
@ -241,11 +296,7 @@ export default {
if (!this.multiple) { if (!this.multiple) {
this.clear(); this.clear();
} }
var index = this.files.push(file)
file = this.files[this.files.push(file) - 1];
this._files[file.id] = file;
this._uploadEvents('add', file);
}, },
_uploadEvents(name, file) { _uploadEvents(name, file) {

@ -1,95 +0,0 @@
import Vue from 'vue/dist/vue.js'
var FileUpload = require('./FileUpload.vue');
// import FileUpload from './FileUpload.vue';
Vue.config.silent = false;
Vue.config.devtools = true;
Vue.filter('formatSize', function(size) {
if (size > 1024 * 1024 * 1024 * 1024) {
return (size / 1024 / 1024 / 1024 / 1024).toFixed(2) + ' TB';
} else if (size > 1024 * 1024 * 1024) {
return (size / 1024 / 1024 / 1024).toFixed(2) + ' GB';
} else if (size > 1024 * 1024) {
return (size / 1024 / 1024).toFixed(2) + ' MB';
} else if (size > 1024) {
return (size / 1024).toFixed(2) + ' KB';
}
return size.toString() + ' B';
});
new Vue({
el:'#app',
components: {
FileUpload:FileUpload,
},
data: {
accept: 'image/*',
size: 1024 * 1024 * 10,
multiple: true,
extensions: 'gif,jpg,png',
// extensions: ['gif','jpg','png'],
// extensions: /\.(gif|png|jpg)$/i,
files: [],
upload: [],
title: 'Add upload files',
drop: true,
auto: false,
name: 'file',
postAction: './post.php',
putAction: './put.php',
headers: {
"X-Csrf-Token": "xxxx",
},
data: {
"_csrf_token": "xxxxxx",
},
events: {
add(file, component) {
console.log('add');
if (this.$parent.auto) {
component.active = true;
}
file.headers['X-Filename'] = encodeURIComponent(file.name)
file.data.finename = file.name
// file.putAction = 'xxx'
// file.postAction = 'xxx'
},
progress(file, component) {
console.log('progress ' + file.progress);
},
after(file, component) {
console.log('after');
},
before(file, component) {
console.log('before');
},
}
},
mounted() {
this.upload = this.$refs.upload.$data
},
methods: {
remove(file) {
var index = this.files.indexOf(file)
if (index != -1) {
this.files.splice(index, 1);
}
},
},
});

@ -5,7 +5,7 @@ module.exports = require('./webpack.config.js');
module.exports.entry = { module.exports.entry = {
'vue-upload-component': './src/main.js', 'vue-upload-component': './src',
} }
module.exports.output.library = 'VueUploadComponent'; module.exports.output.library = 'VueUploadComponent';

@ -3,7 +3,7 @@ var webpack = require('webpack')
module.exports = { module.exports = {
entry: { entry: {
example: ['./src/example.js'], example: ['./example'],
}, },
output: { output: {

Loading…
Cancel
Save