Есть одна функция. Я получаю JSON с локалхоста на /receive/ , вывожу данные на страницу при помощи vue.js
Такая конструкция работает, данные в браузере выводятся:
fetch('/receive/')
.then(response => response.json())
.then(cards =>
new Vue({
el: '#cards',
data: {cards}
})
)
Однако, мне не нравится, что Vue функция находится внутри основной. нужно, чтобы она была отделена, и данные в нее передавались. Но никак не могу понять, как ее переписать. Пробовал так, но не выходит...
Неправильный вариант:
var container = new Vue({
el: '#cards',
data: {cards}
})
fetch('/receive/')
.then(response => response.json())
.then(cards => container.data)
Прошу помощи.
this в fetch свой, сохраняем this до вызова fetch.
var container = new Vue({
el: '#cards',
data: function() {
return {
cards: 'no cards'
}
},
mounted() {
this.getCards();
},
methods: {
getCards() {
let that = this; // The real this
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
return response.json();
})
.then(function(json) {
that.cards = json.title;
});
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.runtime.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="cards"> {{cards}}</div>
Что вы пытались сделать строчкой cards => container.data? Возможно, вы таким образом пытались "затолкнуть" cards внутрь container.data - но на самом деле вы игнорируете параметр и возвращаете container.data.
Чтобы объект изменился - нужно использовать оператор присваивания:
.then(cards => container.cards = cards)
Еще одна ошибка - при инициализации. Переменной cards у вас не существует, а значит и использовать ее невозможно. Нужно использовать полный синтаксис и адекватное начальное значение:
var container = new Vue({
el: '#cards',
data: { cards: [] }
})
Вы можете изменять свойства объекта Vue когда угодно и где угодно, но не выносите логику из объекта.
Например, вот так можно загрузить данные "карточек" при создании, в хуке жизненного цикла created:
var container = new Vue({
el: '#test',
data: {
src: 'https://api.jsonbin.io/b/5afbf3e60fb4d74cdf23de08/1',
cards: ['Loading...']
},
created: function () {
fetch(this.src).then(r => r.json()).then(obj => this.cards = obj.cards);
}
});
body { background-color: #eee7; }
[v-cloak] { visibility: hidden; }
.card-block {
width: 300px; margin: 16px auto; padding: 16px;
text-align: center; font: 300 30px sans-serif;
background-color: #fff; box-shadow: 0 5px 15px 0 #0002;
}
<div id="test" v-cloak>
<div class="card-block" v-for="card in cards">{{card}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
Если требуется реактивная подгрузка асинхронно обновляемых данных, реализуйте в объекте Vue метод, и:
просто вызывайте его, когда нет зависимостей от других свойств в data;
в случае зависимостей, например, когда юзер меняет источник данных и нужно сформировать URL - используйте watch (чтобы вызывать метод обновления при изменении).
Не помещайте асинхронный код в функции computed свойств - это не будет работать, так как работать не должно: значение свойства возвращается синхронно.
Более подробная информация содержится в документации Vue.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости