Загрузка изображений в vue.js из API - PullRequest
1 голос
/ 03 ноября 2019

Учтите это:

  • API загружает манифест метаданных изображения. Изображения имеют идентификатор, и при другом вызове API возвращает изображение base64 из БД. Модель для манифеста - attachmentRecord, а идентификатор - просто поле.
  • Я бы предпочел не загружать эти большие строки в массив (это будет работать).

, поэтомуУ меня есть это (которое лениво загружается при любом изменении манифеста):

<div v-for="(attachment, index) in  attachmentRecord" :key="index">
    <img :src="fetchImage(attachment.id)" />
</div> 

fetchimage() - это обертка для функции axios, которая возвращается из обещания. (записывает это по памяти):

this.axios({
    method: "get",
    url: url,
 }).then(res => res.data)
   .catch(() => {
      alert("Unable to load raw attachment from this task and ID");
    });
 }

Теперь сетевые вызовы проходят нормально, идентификатор проходит правильно, я вижу базовые данные 64, но, похоже, они не превращаются в функцию-оберткуили атрибут src. Это всегда приходит пустым. Я попытался обернуть его в другое обещание, только чтобы вернуть обещание к атрибуту src. Что было бы лучше для этой ситуации в Vue?

Хорошо, пока я внес эти изменения с помощью Константина: я пытался сократить его без вспомогательной функции:

Код шаблона Vue:

<div v-for="(attachment, index) in  attachmentRecord" :key="index">
<img :src="getAttachmentFromTask(attachment.id)" />

базовый метод:

async getAttachmentFromTask(attachmentID) {
  if (!attachmentID) alert("Unknown Attachment!");
  let sendBack = "";
  let url = "/server/..."

  await this.axios({
    method: "get",
    url: url
  })
    .then(res => {
      sendBack = res.data;
    })
    .catch(() => {
      alert("Unable to load raw attachment from this task and ID");
    });
  // >>>>>>>>>alerts base64 correctly; Vue loads [object Promise] in img
  alert(sendBack);
  return sendBack; 
}

1 Ответ

1 голос
/ 03 ноября 2019

Оказывается, Vue не обрабатывает async / await так, как я думал. Поэтому вы должны сохранить данные изображения для каждого вложения в attachmentRecord. Этот метод getAttachmentFromTask теперь обрабатывает это при первом обращении и заполняет свойство data для соответствующего объекта вложения. При последующих вызовах это свойство возвращается, если оно уже заполнено. Обратите внимание на использование Vue.set(), потому что свойство не доступно в исходных данных, но мы хотим, чтобы оно было реактивным. Вы даже можете настроить резервное изображение, например загрузчик, см. Кратковременное мерцание логотипа SOбез текста до появления логотипа большего размера:

new Vue({
  el: '#app',
  data: {
    attachmentRecord: [{
      id: 1
    }]
  },
  methods: {
    getAttachmentFromTask(attachmentIndex, attachmentID) {
      let record = this.attachmentRecord[attachmentIndex];
      if (!record.data) {
        Vue.set(record, 'data', null);
        axios.get('https://kunden.48design.de/stackoverflow/image-base64-api-mockup.json').then((result) => {
          Vue.set(record, 'data', result.data);
        });
      }
      return this.attachmentRecord[attachmentIndex].data;
    }
  }
});
img {
  max-width: 100vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="app">
  <div v-for="(attachment, index) in  attachmentRecord" :key="index">
    <img :src="getAttachmentFromTask(index, attachment.id) || 'https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon.png'" />
  </div>
</div>

старый ответ: (К сожалению, в настоящее время с Vue это не работает)

Запросы Axiosявляются асинхронными по умолчанию. Таким образом, функция не ждет, пока then() вернет значение. Вы можете добавить ключевое слово async перед именем fetchImage и добавить ключевое слово await перед this.axios. Затем обратный вызов then присваивает возвращаемое значение переменной в области действия функции fetchImage, а функция возвращает ее.

async fetchImage() {
    let returnValue;
    await this.axios({
        method: "get",
        url: url,
     }).then(res => { returnValue = res.data; })
       .catch(() => {
          alert("Unable to load raw attachment from this task and ID");
        });
    return returnValue;
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...