Как создать гибкий компонент для загрузки изображений с помощью Vue.js 2.0

1656560414 kak sozdat gibkij komponent dlya zagruzki izobrazhenij s pomoshhyu vuejs

от Кэти Ха

sgciZa3ENsj7rPHGZ8RwvtjYOGq2Hh9NffZu
Кредит фонового изображения: rawpixel на Unsplash.com

Я кодирую с помощью Vue.js 2.0 уже около полугода, и это очень круто. Это невероятно интуитивно понятно и просто. Раздел между HTML/CSS/Javascript делает обучение и кодирование легким.

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

Я сталкивался с этой проблемой, когда пытался создать программу загрузки фотографий профиля для Torneo. Конечно, я мог бы использовать изысканный пакет, но где это весело?

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

Проверьте репозиторий git, чтобы найти весь код.

Желательное поведение

Я создал компонент со следующими целями:

  • Компонент должен иметь возможность активации любым элементом в его родительском компоненте для загрузки изображений
  • Мы должны иметь возможность увидеть предварительный просмотр изображения в родительском компоненте
  • Загруженное изображение должно быть сохранено в формате FormData для отправки на сервер
  • Компонент должен проверить ограничение размера в загруженном изображении (это также можно сделать в серверной части, но это скорее в интерфейсе)
  • Один файл за раз (обратите внимание, что в этом учебнике рассказывается о том, как обрабатывать несколько файлов – все, что вам нужно, это несколько циклов)

Шаг 1: Настройка

Мы начнем с установки простого шаблона webpack. Мы также установим Vuetify, чтобы сэкономить время на стилизации. Заметьте, что все, завернутое в , получен от Vuetify. Поскольку их теги достаточно ясны, я не буду углубляться в это. Оставлю вас прочесть их документацию.

# install the vue-clinpm install vue-cli -g# initiate the webpack-simple, and follow instructionsvue init webpack-simple image-upload
# install dependenciesnpm install
# install Vuetifynpm install vuetify --save
6rqRIITH5v4r7neZhfMbAMJmpTiNTxZY6WZb
Светлый праздник

Шаг 2. Создайте шаблон загрузки изображения

Прекрасно! Теперь, когда мы настроили и установили шаблоны, мы можем удалить любое содержимое заполнителя. Затем мы можем создать новый компонентный файл для загрузчика изображений.

<template>  <div>
    <!-- slot for parent component to activate the file changer -->    <div @click="launchFilePicker()">      <slot name="activator"></slot>    </div>
    <!-- image input: style is set to hidden and assigned a ref so that it can be triggered -->    <input type="file"       ref="file"       :name="uploadFieldName"       @change="onFileChange(          $event.target.name, $event.target.files)"       style="display:none">
    <!-- error dialog displays any potential errors -->    <v-dialog v-model="errorDialog" max-width="300">      <v-card>        <v-card-text class="subheading">{{errorText}}</v-card-text>        <v-card-actions>          <v-spacer></v-spacer>          <v-btn @click="errorDialog = false" flat>Got it!</v-btn>        </v-card-actions>      </v-card>    </v-dialog>
  </div></template>
  1. Чтобы сделать компонент загрузчика изображений способным активироваться любым элементом родительского компонента, мы можем воспользоваться функцией «слот» Vue.
  2. Поскольку мы хотим, чтобы «триггер» для ввода находился в родительском компоненте, мы хотим, чтобы функциональные возможности ввода файла были в дочернем компоненте, не имея возможности его увидеть. Мы можем изменить стиль ввода на «display:none», чтобы скрыть его.
  3. Входу изображения назначается ссылка, чтобы, когда нажать на слот, мы могли активировать вход изображения по его ссылке.
  4. Чтобы сделать программу загрузки изображений более удобной для пользователей, мы можем использовать диалоговое окно для отображения любых возможных ошибок.
rt-C1o7SHEIhEa4qZCHHLWutfGltKOLeQu0w

Далее мы можем использовать магию Vue.js в части JavaScript, чтобы внести немного жизни в наш компонент:

<script>
  export default {
    name: 'image-input',
    data: ()=> ({      errorDialog: null,      errorText: '',      uploadFieldName: 'file',      maxSize: 1024    }),
    props: {          // Use "value" here to enable compatibility with v-model      value: Object,    },
    methods: {      launchFilePicker(){        this.$refs.file.click();      },
      onFileChange(fieldName, file) {        const { maxSize } = this        let imageFile = file[0]          //check if user actually selected a file        if (file.length>0) {          let size = imageFile.size / maxSize / maxSize          if (!imageFile.type.match('image.*')) {            // check whether the upload is an image            this.errorDialog = true            this.errorText="Please choose an image file"          } else if (size>1) {            // check whether the size is greater than the size limit            this.errorDialog = true            this.errorText="Your file is too big! Please select an image under 1MB"          } else {            // Append file into FormData & turn file into image URL            let formData = new FormData()            let imageURL = URL.createObjectURL(imageFile)            formData.append(fieldName, imageFile)
            // Emit FormData & image URL to the parent component            this.$emit('input', { formData, imageURL })          }        }      }    }  }</script>

5. Чтобы сделать компонент загрузчика изображений совместимым с v-model, используйте «value» в props. Любые данные, излучаемые компонентом, будут записаны в параметр «value».

6. При нажатии активатора ввода файлов в родительском компоненте «this.$refs.file.click()» используется для активации селектора файлов.

7. После того, как пользователь выберет что-нибудь из селектора файлов / закроет селектор файлов, нам нужно проверить:

  • Действительно ли пользователь выбрал файл
  • Является ли файл изображением
  • Превышает размер файла лимит (часто это хорошая идея, когда речь идет о загрузке пользователями)

8. Если файл, выбранный пользователем, отвечает требованиям, создайте элемент FormData и добавьте файл к элементу, используя имя, которое примет ваш сервер. Также преобразуйте файл изображения в URL объекта, чтобы родительский компонент мог прочитать его для предварительного просмотра.

9. Отправляйте данные (FormData для загрузки на сервер и imageURL для предварительного просмотра) к родительскому компоненту.

Шаг 3: Создайте родительский компонент

62ZYpFxJIzdgxHdotiXCuCAfmUAJpI4nl7C6
Вид на конечный продукт, чтобы поощрить вас продолжать читать

В родительском компоненте мы можем визуализировать функциональность дочернего компонента.

<template>  <v-app id="app" class="mt-0">    <v-container grid-list-xl>      <image-input v-model="avatar">        <div slot="activator">          <v-avatar size="150px" v-ripple v-if="!avatar" class="grey lighten-3 mb-3">            <span>Click to add avatar</span>          </v-avatar>          <v-avatar size="150px" v-ripple v-else class="mb-3">            <img :src=" alt="avatar">          </v-avatar>        </div>      </image-input>      <v-slide-x-transition>        <div v-if="avatar && saved == false">          <v-btn class="primary" @click="uploadImage" :loading="saving">Save Avatar</v-btn>        </div>      </v-slide-x-transition>    </v-container>  </v-app></template>
  1. Заверните элемент активатора в
    и дайте дочернему компоненту знать, что он принадлежит к слоту, который мы назвали «активатором».
  2. Используйте v-if и v-else в Vue, чтобы отобразить запрос на загрузку или предварительный просмотр аватара в зависимости от того, выбрал ли пользователь файл.
  3. Условно отобразите кнопку, чтобы сохранить изменения пользователя.

Почти сделано! Далее время добавить немного Javascript к родительскому компоненту:

<script>import ImageInput from './components/ImageInput.vue'
export default {  name: 'app',  data () {    return {      avatar: null,      saving: false,      saved: false    }  },  components: {    ImageInput: ImageInput  },  watch:{    avatar: {      handler: function() {        this.saved = false      },      deep: true    }  },  methods: {    uploadImage() {      this.saving = true      setTimeout(() => this.savedAvatar(), 1000)    },    savedAvatar() {      this.saving = false      this.saved = true    }  }}</script>

4. В части сценария импортируйте дочерний компонент.

5. Когда пользователь нажимает кнопку «Сохранить», загрузите аватар на сервер (обратите внимание, что я имитирую загрузку в коде выше. На самом деле мы используем axios для загрузки файла на сервер. Бекенд затем сохраняет файл в файловой системе и передает путь к файлу в данных ).

XfCSI5PrA9VekPsJGcMK5lcd9z7nkG4BPXZD
Вы очень классные, что зашли так далеко ❤

Это! Есть много возможностей для улучшения этого компонента — таких как передача реквизитов для изменения размера загружаемого изображения, обработка нескольких файлов и т.д. Если вы видите потенциальные моменты для улучшения или заметили ошибку в моем коде, оставьте комментарий!

Опять же не стесняйтесь проверять репозиторий git для всего кода.

Наконец, беззастенчивая розетка: если вы случайно интересуетесь спортом, посмотрите Torneo – спортивный стартап, который я помогал развивать.

Добавить комментарий

Ваш адрес email не будет опубликован.