Я создал компонент, который отображает предварительные просмотры статей в блогах.Этот компонент имеет нумерацию страниц, и при выборе новой страницы я обновляю массив предварительных просмотров статьи.Список статей извлекается из API-интерфейса JSON с сервера server1.Ответ содержит информацию для извлечения каждой статьи с сервера 2. Затем я запускаю x асинхронных выборок на сервер 2, столько же, сколько элементов в первом ответе.В этих ответах я обновляю элементы в массиве.
Я новичок в vue, но после некоторой борьбы заставил это работать.Теперь я пытаюсь добавить спиннер в превью статей, пока загружаются отдельные статьи.Моя идея состояла в том, чтобы посмотреть в компоненте предварительного просмотра обновления статьи и показать счетчик в зависимости от этого.К сожалению, это не работает, и теперь я начинаю сомневаться в моей реализации.Я заметил, что часы в предварительном просмотре не вызываются для каждого компонента предварительного просмотра, но каждый предварительный просмотр обновляется и отображается правильно.Я предполагаю, что это из-за системы обмена сообщениями, но мне не удается это исправить.
Мой вопрос состоит из двух частей:
- Является ли моя реализация правильным способом решения этой проблемы?Чтобы заставить это работать, мне приятно «стереть» массив, потому что в противном случае новые статьи «перезаписывают» старые, и это было видно.
- Как я могу справиться со счетчиками.Почему часы не срабатывают и как я могу это исправить?В приведенном ниже коде у меня есть некоторые записи консоли.Я вижу 10 раз «async» и каждый раз различное количество «watch», никогда 10.
Полный код на github здесь: Home и ArticlePreview.Это наиболее важные части:
Home:
<template>
<div class="container article">
<div class="row" v-for="(article, index) in articles" :key="index">
<ArticlePreview v-bind:blogEntry="article"></ArticlePreview>
</div>
<b-pagination-nav :use-router="true" :link-gen="generateLink" align="center" :number-of-pages="nofPages" v-model="pageIndex" />
</div>
</template>
data: function ()
{
return {
articles: <BlogEntry[]> [],
nofPages: 1
}
},
loadContent()
{
fetch("./api/v1/articles.php?page=" + this.pageIndex)
.then(response => response.json())
.then((data) =>
{
this.nofPages = Math.ceil(data.nofItems/10);
this.articles.splice(0);
this.articles.splice(data.data.length);
let index :number;
for(index = 0; index < data.data.length; index++)
{
createArticleAsync(data.data[index].name, data.data[index].permlink).then(function(this: any, index: number, article: BlogEntry)
{
console.log('async');
Vue.set(this.articles, index, article);
}.bind(this, index));
}
})
},
ArticlePreview:
<template>
<div class="container-fluid">
<div class="row" v-if="blogEntry">
<template v-if="blogEntry">
<div class="imageframe col-md-3">
<div class="blog-image">
<img :src="blogEntry.previewImage" style="border-radius: 5px;">
</div>
</div>
<div class="col-md-9">
<h5 class="font-weight-bold" style="margin-top:5px;"><router-link :to="{ name: 'Article', params: {author: blogEntry.author, permlink: blogEntry.permlink } }">{{blogEntry.title}}</router-link></h5>
<div class="multiline-ellipsis">
<p>{{blogEntry.previewBody}}</p>
</div>
<span class="metadata"><i>by <a :href="AuthorBlogLink">{{blogEntry.author}}</a> on {{blogEntry.created | formatDate}}</i></span>
</div>
</template>
<template v-else>
<p>Loading</p>
</template>
</div>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import VueRouter from 'vue-router';
import {formatDate} from "../utils/utils";
export default Vue.extend({
props: [
'blogEntry'
],
data: function ()
{
return {
loading: true
}
},
watch:
{
blogEntry(newValue)
{
console.log('watch');
if(newValue)
this.loading = false;
else
this.loading = true;
}
}
});
</script>