Lab / Vue JS

Как сделать предпросмотр изображения перед загрузкой на VueJS

Например, вы создаете приложение, в котором ваши пользователи могут загружать изображения в свои профили. Вероятно, вы хотите просмотреть эти изображения перед загрузкой - как правило, это хороший способ взаимодействия с вашим интерфейсом.

В этом небольшом уроке мы научимся писать униаерсальный переиспользуменный компонет на Vue JS для подобных целей.

Шаблон компонента

Для начала давайте создадим Vue шаблон нашего будущего компанента:

<template id="image-input-template">
 <div class="Image-input">
 <div class="Image-input__image-wrapper">
 <i v-show="! imageSrc" class="icon fa fa-picture-o"></i>
 <img v-show="imageSrc" class="Image-input__image" :src="imageSrc">
 </div>

 <div class="Image-input__input-wrapper">
 Choose
 <input @change="previewThumbnail" class="Image-input__input" name="thumbnail" type="file">
 </div>
 </div>
</template>

Здесь нам важны только два пунтка, это свойствр imageSrc загружаемого изображения и событие @change="previewThumbnail" которое мы повесили на поле file input, которое будет срабатывать каждый раз когда мы будем загружать изображение.

Компонент

Давайте теперь напишем сам компонент:

Vue.component('image-input', {
 template: '#image-input-template',

 props: [ 'imageSrc' ],

 methods: {
 previewThumbnail: function(event) {
 var input = event.target;

 if (input.files && input.files[0]) {
 var reader = new FileReader();
 var vm = this;

 reader.onload = function(e) {
 vm.imageSrc = e.target.result;
 }

 reader.readAsDataURL(input.files[0]);
 }
 }
 }
});

Сначала мы указываем компоненту на ранее созданный шаблон и свойство которое он будет принимать — imageSrc. Затем выполняем обработчик событий, который использует объект FileReader для доступа к данным изображения хранящегося в DOM элементе поля, что бы достать от туда данные для предпросмотра.

Если вам кажется странным, почему мы определили imageSrc как свойство, а не как набор данных, это потому, что в некоторых случаях нам может понадобиться отображать уже загруженные ранее изображения (например, когда пользователь редактирует свой профиль).

Стили CSS

Наш компонент готов к использованию, однако для полного счастья нам необходимо стилизовать его при помощи CSS подогнав под общий дизайн вашего приложения. Ниже я приожу мой пример кода, который вы можете извенить на ваше усмотрение.

.Image-input {
 display: flex;
}

.Image-input__image-wrapper {
 flex-basis: 80%;
 height: 150px;
 flex: 2.5;
 border-radius: 1px;
 margin-right: 10px;
 overflow-y: hidden;
 border-radius: 1px;
 background: #eee;
 justify-content: center;
 align-items: center;
 display: flex;
}

.Image-input__image-wrapper > .icon {
 color: #ccc;
 font-size: 50px;
 cursor: default;
}

.Image-input__image {
 max-width: 100%;
 border-radius: 1px;
}

.Image-input__input-wrapper {
 overflow: hidden;
 position: relative;
 background: #eee;
 border-radius: 1px;
 float: left;
 flex: 1;
 display: flex;
 justify-content: center;
 align-items: center;
 color: rgba(0,0,0,0.2);
 transition: 0.4s background;
}

.Image-input__input-wrapper:hover {
 background: #e0e0e0;
}


.Image-input__input {
 cursor: inherit;
 display: block;
 font-size: 999px;
 min-height: 100%;
 opacity: 0;
 position: absolute;
 right: 0;
 text-align: right;
 top: 0;
 cursor: pointer;
}

Осталось лишь разместить данный компонент в шаблоне вашего приложения:

<image-input image-src=""></image-input>

И вызвать экземпляр root Vue

new Vue({
 el: 'body'
});

Ну вот и всё, теперь у вас есть переиспользуемый компонент для загрузки изображений на Vue js.