Получить Vue, чтобы обновить вид / компонент
Я застрял на перекрестке с компонентом, над которым я работаю.
У меня есть следующий компонент "RecentUpdates"
В нем я передаю реквизиты нескольким другим компонентам, как вы можете видеть в верхней части файла.
Моя проблема заключается в том, что при добавлении нового сообщения я не могу понять, как вернуть правильный массив объекта обновления, и я также не могу найти правильный "путь Vue" для обновления данных, которые передаются в "PostList". " составная часть.
<template>
<div>
<PostFilter v-on:selectedCategory="getSelectedPosts" v-on:showAllPosts="showAllPosts" :user="user" :categories="categories"/>
<PostList v-if="recent_posts[0]" :categories="categories" :posts="recent_posts[0]" :user="user"/>
<Pagination v-on:getPreviousPage="getPreviousPage" v-on:getNextPage="getNextPage"/>
</div>
</template>
<script>
import PostList from './PostList';
import PostFilter from './PostFilter';
import Pagination from './Pagination';
import EventBus from '../event-bus';
export default {
name: 'RecentUpdates',
data: () => ({
errors: [],
recent_posts: [],
}),
props: ['categories', 'user'],
components: {
PostList,
PostFilter,
Pagination
},
created() {
if (this.user.meta.selected_categories[0] == 0) {
this.showAllPosts();
}
// do not call here, not working as expected
// is switching selected category to an incorrect one
// this.updateList();
this.getSelectedCategory();
},
watch: {
recent_posts: function(newValue) {
EventBus.$on('addPost', function(newPost) {
console.log(newPost);
this.$forceUpdate();
//this.recent_posts.push(newPost);
//this.$set(this.recent_posts, newPost, newPost);
// this.$nextTick(function () {
// this.recent_posts.push(newPost);
// });
});
console.log(this.recent_posts[0]);
// this.$nextTick(function () {
// console.log(this.recent_posts[0]) // => 'updated'
// });
// if (this.user.meta.selected_categories[0] == 0) {
// EventBus.$on('addPost', this.showAllPosts);
// } else {
// EventBus.$on('addPost', this.getSelectedCategory);
// }
//this.updateList();
}
},
methods: {
// updateList() {
// if (this.user.meta.selected_categories[0] == 0) {
// EventBus.$on('addPost', this.showAllPosts);
// //EventBus.$emit('newPost');
// } else {
// EventBus.$on('addPost', this.getSelectedCategory);
// //EventBus.$emit('newPost');
// }
// },
getSelectedCategory() {
let categoryId = this.user.meta.selected_categories[0];
this.getSelectedPosts(categoryId);
},
showAllPosts() {
axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]',
{headers: {'X-WP-Nonce': portal.nonce}})
.then(response => {
this.recent_posts = [];
//this.recent_posts = response.data;
//console.log(response.data);
this.recent_posts.push(response.data);
console.log(this.recent_posts[0]);
})
.catch(e => {
this.errors.push(e);
});
},
getSelectedPosts(categoryId) {
axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&categories=' + categoryId,
{headers: {'X-WP-Nonce': portal.nonce}})
.then(response => {
this.recent_posts = [];
//console.log(response.data);
this.recent_posts.push(response.data);
console.log(this.recent_posts[0]);
})
.catch(e => {
this.errors.push(e);
});
},
/**
* Pagination methods
*
*/
getPreviousPage(page) {
axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&page=' + page,
{headers: {'X-WP-Nonce': portal.nonce}})
.then(response => {
this.recent_posts = response.data;
})
.catch(e => {
this.errors.push(e);
});
},
getNextPage(page) {
axios.get('/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&page=' + page,
{headers: {'X-WP-Nonce': portal.nonce}})
.then(response => {
this.recent_posts = response.data;
})
.catch(e => {
this.errors.push(e);
});
}
},
}
</script>
<style>
</style>
2 ответа
Так что я вижу ряд проблем при чтении вашего кода.
- У тебя есть
recent_posts
свойство данных, которое является массивом. Когда вы делаете ajax-вызов, чтобы получить сообщения, вы нажимаете ответ, который также является массивом вrecent_posts
массив. Зачем? Почему бы просто не установитьrecent_posts = response.data
? Тогда вам не придется проходить мимоrecent_posts[0]
вокруг. - Вы настраиваете свой
EventBus
обработчик внутри наблюдателя. Это действительно необычно. Обычно вы устанавливаете обработчик внутриcreated
или жеmounted
, this
Внутри обработчик EventBus, скорее всего, относится к EventBus, а не к вашему Vue. В идеале вы должны установить обработчик как метод для компонента, который уже связан с Vue. Что-то вродеEventBus.$on("addPost", this.addPost)
,- После того, как вы все это сделали, добавление нового поста должно быть таким простым, как
this.recent_posts.push(newPost)
,
Вот что я мог бы порекомендовать.
export default {
name: 'RecentUpdates',
data(){
return {
errors: [],
recent_posts: []
}
},
props: ['categories', 'user'],
components: {
PostList,
PostFilter,
Pagination
},
created() {
if (this.user.meta.selected_categories[0] == 0) {
this.showAllPosts();
}
this.getSelectedCategory();
EventBus.$on("addPost", this.addPost)
},
beforeDestroy(){
EventBus.$off("addPost", this.addPost)
},
methods: {
getPosts(url){
axios.get(url, {headers: {'X-WP-Nonce': portal.nonce}})
.then(response => this.recent_posts = response.data)
.catch(e => this.errors.push(e))
},
showAllPosts() {
const url = '/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]';
this.getPosts(url);
},
getSelectedPosts(categoryId) {
const url = '/wp-json/wp/v2/posts?_embed=true&status=[publish,resolved,unresolved]&categories=' + categoryId;
this.getPosts(url);
},
addPost(newPost){
this.recent_posts.push(newPost)
},
... //other methods
},
}
Попробуйте использовать kebab-case в слушателях событий вместо camelCase:
- Пример: v-on:selectedCategory="getSelectedPosts" должно быть v-on:selected-category="getSelectedPosts".
- Пример: v-on:showAllPosts="showAllPosts" должно быть v-on:show-all-posts="showAllPosts" или даже с использованием ярлыка @show-all-posts="showAllPosts".
ОБНОВЛЕНИЕ: Если вы можете предоставить код других компонентов, чтобы у нас было более четкое представление о вашей проблеме, но вы хотите отслеживать только изменения, которые происходят с объектом или массивом, в vue.js, вам нужно тщательно их отслеживать. Ваш наблюдатель должен быть:
watch: {
recent_posts: {
deep: true,
handler: function( oldValue, newValue) {
console.log( "recent_posts has changed" );
// A post has been added, updated or even deleted
}
}
}