Как получить реквизит Vue и данные, извлеченные из вызова AJAX в смонтированных() и созданных() крючках
Я просто пытаюсь установить данные, полученные из вызова 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

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
может быть лучше реализована как вычисляемое свойство.

mounted()
срабатывает, когда компонент монтируется в DOM или, по крайней мере , это то, что я понимаю в документе , но не гарантирует, что дочерние компоненты также были смонтированы, что не является моим случаем, потому что я хочу, чтобы данные отображались в том же компоненте. Итак, почему отображение данных в шаблоне, но не в моем mounted()
lifecycle hook? Я бы попробовал использовать this.$nextTick()
но я столкнусь с проблемой о ключевом this
.

mounted
крюк вызывается только при первом отображении компонента. Последующий рендеринг вызовет updated
Хук вместо этого. При первом запуске шаблона массив пуст. После загрузки данных с сервера шаблон будет запущен снова, показывая правильные значения. Все это может произойти так быстро, что вы даже не заметите начального рендеринга. Использование $nextTick
не поможет. Это будет ждать до тех пор, пока рендеринг не будет завершен, но он не будет ждать асинхронной загрузки данных. Вам нужно узнать, как this
работает, а не избегать его: функции стрелок-ваш друг.