让 Vue 更新 view/component
Get Vue to update view/component
我正在处理一个组件,正处于十字路口。
我有以下组件"RecentUpdates"
在其中,我将 props 传递给其他几个组件,正如您从文件顶部看到的那样。
我的问题是在添加新的 post 时,我无法弄清楚如何取回正确的更新对象数组,我也无法弄清楚正确的 'Vue way' 来更新数据传递给 "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>
尝试在事件侦听器中使用 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
}
}
}
所以我在阅读您的代码时发现了很多问题。
- 你有一个
recent_posts
数据属性,它是一个数组。当您进行 ajax 调用以获取 post 时,您将 也是 数组的响应推送到 recent_posts
数组中。为什么?为什么不直接设置 recent_posts = response.data
?这样你就不用绕着recent_posts[0]
转了。
- 您正在观察程序中设置
EventBus
处理程序。这真的很不寻常。通常,您会在 created
或 mounted
. 中设置处理程序
EventBus 处理程序中的 this
可能指的是 EventBus 而不是您的 Vue。理想情况下,您可以将处理程序设置为组件上的一个方法,该组件已经绑定到 Vue.类似于 EventBus.$on("addPost", this.addPost)
.
- 完成所有这些后,添加新的 post 应该像
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
},
}
我正在处理一个组件,正处于十字路口。
我有以下组件"RecentUpdates"
在其中,我将 props 传递给其他几个组件,正如您从文件顶部看到的那样。
我的问题是在添加新的 post 时,我无法弄清楚如何取回正确的更新对象数组,我也无法弄清楚正确的 'Vue way' 来更新数据传递给 "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>
尝试在事件侦听器中使用 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
}
}
}
所以我在阅读您的代码时发现了很多问题。
- 你有一个
recent_posts
数据属性,它是一个数组。当您进行 ajax 调用以获取 post 时,您将 也是 数组的响应推送到recent_posts
数组中。为什么?为什么不直接设置recent_posts = response.data
?这样你就不用绕着recent_posts[0]
转了。 - 您正在观察程序中设置
EventBus
处理程序。这真的很不寻常。通常,您会在created
或mounted
. 中设置处理程序
EventBus 处理程序中的 this
可能指的是 EventBus 而不是您的 Vue。理想情况下,您可以将处理程序设置为组件上的一个方法,该组件已经绑定到 Vue.类似于EventBus.$on("addPost", this.addPost)
.- 完成所有这些后,添加新的 post 应该像
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
},
}