Last active
January 5, 2021 12:55
-
-
Save jlccaires/597712690fdf3941ab10339f29bab96e to your computer and use it in GitHub Desktop.
Vue upload, gallery, preview, progress using vue-upload-component, Buefy, ElementUI and filesize.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<b-modal :active="true" :onCancel="close"> | |
<div class="modal-card"> | |
<section class="modal-card-body"> | |
<nav class="level"> | |
<div class="level-left"> | |
<el-tooltip v-if="errorFiles.length" placement="bottom" effect="light"> | |
<div slot="content"> | |
<div> | |
Alguns arquivos não puderam ser enviados: | |
<br> | |
<div> | |
<b v-for="error in errorFiles">{{error}}<br></b> | |
</div> | |
</div> | |
</div> | |
<a class="button is-danger"> | |
<b-icon icon="exclamation"/> | |
</a> | |
</el-tooltip> | |
</div> | |
<div class="level-item has-text-centered"> | |
<file-upload | |
ref="upload" | |
v-model="files" | |
:active="true" | |
:drop="true" | |
:multiple="true" | |
:thread="2" | |
:accept="'image/png,image/gif,image/jpeg,image/jpg'" | |
:extensions="'gif,jpg,jpeg,png'" | |
:size="10485760" | |
:timeout="1200000" | |
:post-action="'http://httpbin.org/post'" | |
@input-file="inputFile"> | |
<a class="button is-info"> | |
<b-icon icon="plus" /> | |
<span>Arquivos</span> | |
</a> | |
</file-upload> | |
</div> | |
</nav> | |
<div class="columns is-multiline is-mobile"> | |
<div v-for="file in files" class="column is-2-desktop is-3-tablet is-4-mobile"> | |
<div class="card"> | |
<div class="card-image"> | |
<div v-if="!file.success" class="remove-container has-text-right"> | |
<button class="delete" @click="remove(file)"></button> | |
</div> | |
<figure class="image is-1by1"> | |
<img v-if="file.blob" :src="file.blob" width="100%" height="auto" /> | |
</figure> | |
</div> | |
<div class="has-text-centered"> | |
<small v-if="file.active">{{ file.speed | filesize }}/s</small> | |
</div> | |
<el-progress :text-inside="!file.error" :stroke-width="18" :status="file.success ? 'success' : file.error ? 'exception' : null" :percentage="Math.trunc(file.progress)"></el-progress> | |
<footer class="card-footer"> | |
<p class="card-footer-item has-text-left"> | |
<el-tooltip :content="file.name" placement="bottom" effect="light" :open-delay="250"> | |
<span class="ellipsis" v-text="file.name"></span> | |
</el-tooltip> | |
<small>{{ file.size | filesize }}</small> | |
</p> | |
</footer> | |
</div> | |
</div> | |
</div> | |
<div v-show="$refs.upload && $refs.upload.dropActive" class="drop-active"> | |
</div> | |
</section> | |
</div> | |
</b-modal> | |
</template> | |
<script> | |
import FileUpload from 'vue-upload-component' | |
export default { | |
components: { | |
FileUpload | |
}, | |
props: ['projectId', 'galleryId'], | |
data() { | |
return { | |
files: [] | |
} | |
}, | |
mounted() { | |
var self = this | |
}, | |
watch: { | |
files() { | |
var complete = true | |
this.files.forEach(function(file){ | |
complete &= !file.active && (file.success || file.error) | |
}) | |
if (complete && this.files.length > 0) { | |
this.uploadComplete() | |
} | |
} | |
}, | |
computed: { | |
errorFiles() { | |
const errorFiles = [] | |
this.files.forEach(function(file){ | |
if (file.error) { | |
errorFiles.push(file.name) | |
} | |
}) | |
return errorFiles | |
} | |
}, | |
methods: { | |
close() { | |
this.$router.back() | |
}, | |
inputFile(newFile, oldFile) { | |
if (newFile && !oldFile) { | |
var URL = window.URL || window.webkitURL | |
if (URL && URL.createObjectURL) { | |
this.$refs.upload.update(newFile, {blob: URL.createObjectURL(newFile.file)}) | |
this.$refs.upload.active = true | |
} | |
} | |
}, | |
remove(file) { | |
this.$refs.upload.remove(file) | |
}, | |
uploadComplete() { | |
this.$notify({ | |
title: 'Envio concluído!', | |
message: 'Suas imagens foram enviadas', | |
type: 'success' | |
}) | |
} | |
} | |
} | |
</script> | |
<style scoped> | |
.modal-card { | |
height: 100vh; | |
} | |
.modal-card { | |
margin: 0; | |
width: 100%; | |
} | |
.drop-active { | |
border: 10px solid green; | |
top: 0; | |
bottom: 0; | |
right: 0; | |
left: 0; | |
position: fixed; | |
opacity: .4; | |
background: #000; | |
} | |
.card-footer-item { | |
display: grid; | |
padding: 5px 10px 5px 10px; | |
justify-content: flex-start; | |
} | |
.ellipsis { | |
left: 0; | |
right: 0; | |
white-space: nowrap; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
} | |
.remove-container { | |
width: 100%; | |
z-index: 1; | |
padding: 6px; | |
position: absolute; | |
} | |
img { | |
object-fit: cover; | |
} | |
</style> |
Author
jlccaires
commented
Jun 18, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment