Vue
by Trina Lu
HTML
<div id="app">
<h1>
File upload
</h1>
<file-input />
</div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
Vue
const FileInput = {
template: `
<div class="file-input__wrapper">
<input type="file" multiple @change="onFileInputChange" ref="fileInput" hidden>
<button class="file-input__button" @click="triggerFileUpload">Upload file</button>
<ul>
<li v-for="file in files" class="file-input__image">
{{file.source.name}}
<input v-model="file.alt" />
<img v-if="file.image" :src="file.image" width="50" />
</li>
</ul>
</div>
`,
data() {
return {
files: []
}
},
methods: {
triggerFileUpload() {
this.$refs.fileInput.click();
},
onFileInputChange(e) {
const nextFiles = Array.from(e.target.files).map(file => {
const data = {
source: file,
image: '',
alt: ''
};
this.readFileImage(file)
.then(image => data.image = image)
return data;
});
this.files = [...this.files, ...nextFiles];
},
readFileImage(file) {
return new Promise(resolve => {
const reader = new FileReader();
reader.onload = function(e) {
resolve(e.target.result);
};
reader.readAsDataURL(file);
});
}
}
}
const App = new Vue({
el: '#app',
components: {
FileInput
}
})