Как получить реквизит Vue и данные, извлеченные из вызова AJAX в смонтированных() и созданных() крючках

Как получить реквизит Vue и данные, извлеченные из вызова AJAX в смонтированных() и созданных() крючках

14.09.2019 11:52:15 Просмотров 60 Источник

Я просто пытаюсь установить данные, полученные из вызова AJAX, используя встроенный fetch()в переменную данных courts, контекст ключевого fetch()может измениться. Однако, если я привязываю переменную thisкак prop к моему дочернему компоненту, он отображается в HTML, но все же я не могу получить доступ к prop из, например, courtsи created()крючков жизненного цикла.

Я уже читал этот вопрос, который указывает на проблему с ключевым mounted().

Из-за асинхронного рабочего процесса JavaScript я также проверяю, получаю ли я данные с помощью this, который я делаю, но не в моем дочернем компоненте в качестве опоры.

У меня есть Babel, загруженный из Webpack, и я пытался разобраться с ним с помощью setTimeout()

Я тоже async awaitдля доступа к моей опоре, но это дает мне пустой массив.

Кортмап.vue (дочерний компонент)

EDIT: Извините, я забыл использовать <template> <div class="container"> <court-map v-bind:items="courts"></court-map> <navbar v-bind:items="courts"></navbar> </div> </template> <script> import CourtMap from './components/CourtMap.vue'; import Navbar from './components/Navbar.vue'; export default { components: { 'navbar': Navbar, 'court-map': CourtMap }, data() { return { courts: [], } }, created() { this.getCourts(); }, methods: { getCourts() { let _self = this; fetch('/api/courts', { method: 'GET', headers: { 'Accept': 'application/json', 'Content-type': 'application/json' } }) .then(response => response.json()) .then(data => { _self.courts = data; // With alias this.courts = data; console.log(_self.courts); // Shows my data }) .catch(error => console.error(error)); console.log(_self.courts); // No longer shows my data setTimeout(function() { console.log(_self.courts); // Shows my data console.log(this.courts); // Undefined }, 3000); } } } </script> в индексе переменной.

this.$props.items

Индекс.js (где я запускаю свое приложение Vue)

this

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

Заранее спасибо, что нашли время прочитать это.

У вопроса есть решение - Посмотреть?

Ответы - Как получить реквизит Vue и данные, извлеченные из вызова AJAX в смонтированных() и созданных() крючках / How to get Vue props and data fetched from within an AJAX call in the mounted() and created() hooks

Является ответом!
skirtle

15.09.2019 01:43:38

Давайте проясним некоторые вещи.

thisне просто случайно меняется. Он изменяется при вводе новой функции. Использование псевдонима, такого как self, исторически было способом избежать этой проблемы, но в вашем случае вы используете функции со стрелками. Функция стрелки не изменит thisзначение из окружающей области.

Теперь давайте посмотрим, почему это не работает:

mounted () {
    console.log(this.items); // Doesn't show the data
    setTimeout(function() {
        console.log(this.items); // Doesn't show the data too
    }, 3000);

В первый раз он пытается получить доступ this.itemsслишком рано. Асинхронная fetchеще не завершена.

Во второй раз, внутри setTimeout, у нас есть новая функция, поэтому thisзначение изменяется. С помощью функции стрелки должны отображаться правильные данные:

setTimeout(() => {
    console.log(this.items);
}, 3000);

Предполагая, конечно, что данные загружаются в течение 3 секунд.

Конечно, таймер - это не правильный способ справиться с этим.

Самый простой вариант-не создавать дочерние компоненты, пока данные не будут доступны:

<court-map v-if="courts.length" :items="courts"></court-map>

v-ifпредотвратит создание компонента до тех пор, пока в массиве не появятся записи. Выполнение этого способа гарантируетcreatedи mountedкрючки не будут запущены, пока courtsне будут готовы к передаче в качестве items.

Возможно, пустой массив не является лучшим выбором начального значения здесь, поскольку трудно сказать, что кроме пустого массива, возвращенного сервером. Если вместо этого мы используем null значение изначально, что становится немного проще.

data() {
    return {
        courts: null
    }
},

с:

<court-map v-if="courts" :items="courts"></court-map>

Другой кодекс, который использует courts, возможно, нуждается в соответствующей корректировке.

Кроме того, если вы не хотите использовать v-ifдля задержки создания дочерних элементов, вы можете использовать watchв дочернем элементе, чтобы дождаться изменения items. Затем вы можете инициировать любые действия, которые должны произойти.

Дополнительная заметка о том, почему эта строка не работает:

longitude: this.items[firstIndex].longitude

Итак, первая проблема заключается в том, что this.itemsеще не загружены (как описано выше). Вторая проблема будет заключаться в том, что firstIndexне определен. firstIndex: 0на несколько строк выше это не имеет значения. this.items[firstIndex]пытается использовать локальную переменную firstIndex, которая не существует.

Не зная больше, трудно сказать, но positionможет быть лучше реализована как вычисляемое свойство.

https://stackoverflow.com/questions/57939174/how-to-get-vue-props-and-data-fetched-from-within-an-ajax-call-in-the-mounted/57939815#comment102299002_57939815
Во-первых, спасибо за ответ, я ценю это. Позволь спросить тебя кое о чем. Теоретически mounted()срабатывает, когда компонент монтируется в DOM или, по крайней мере , это то, что я понимаю в документе , но не гарантирует, что дочерние компоненты также были смонтированы, что не является моим случаем, потому что я хочу, чтобы данные отображались в том же компоненте. Итак, почему отображение данных в шаблоне, но не в моем mounted()lifecycle hook? Я бы попробовал использовать this.$nextTick()но я столкнусь с проблемой о ключевом this.
https://stackoverflow.com/questions/57939174/how-to-get-vue-props-and-data-fetched-from-within-an-ajax-call-in-the-mounted/57939815#comment102302517_57939815
@SalvaLópez mountedкрюк вызывается только при первом отображении компонента. Последующий рендеринг вызовет updatedХук вместо этого. При первом запуске шаблона массив пуст. После загрузки данных с сервера шаблон будет запущен снова, показывая правильные значения. Все это может произойти так быстро, что вы даже не заметите начального рендеринга. Использование $nextTickне поможет. Это будет ждать до тех пор, пока рендеринг не будет завершен, но он не будет ждать асинхронной загрузки данных. Вам нужно узнать, как thisработает, а не избегать его: функции стрелок-ваш друг.
Закрыть X