我的 Vue 应用程序使用 Vuex 和 Vue Apollo 时遇到问题,所以我正在处理分页,问题是它没有向我显示商店中的事件,也没有向我显示分页中的数字任何一个。问题还在于,在没有事件的第 0 页上检测到分页,而不是在应该已显示事件的第一页上检测到分页。有人会好心告诉我我哪里做错了吗?我将非常感谢您帮助解决这个问题。
index.js
state: {
limit: 12,
page: 0,
events: [],
},
mutations: {
limit(state, limit) {
state.limit = limit
},
page(state, page) {
state.page = page
},
allEvents(state, allEvents) {
state.events = allEvents;
},
},
actions: {
async fetchEvents({ commit, state }) {
try {
const response = await provider().clients.graphqlClientPortal.query({
query: gql`
query LiveEvents($limit: Int!, $page: Int!){
liveEvents(pagination:{limit:$limit, page:$page}, order:{startsAt:{direction: DESC}}){
total,
data{
id,
name,
stub,
description,
mainImage{
id,
uri
},
location,
type,
layout
chat,
liveStream{
endsAt,
startsAt
}
}
}
}
`,
variables: {
limit: state.limit,
page: state.page
},
});
console.log(response.data)
commit('allEvents', response.data.liveEvents.data);
commit("limit", response.data.liveEvents.data.limit),
commit("page", response.data.liveEvents.page)
//commit("total", response.data.liveEvents.total)
} catch (error) {
console.log('error-message', error.graphQLErrors)
}
},
}
List.vue
<template>
// displaying events
<div v-for="(event, index) in displayedPosts" :key="index">
<h2>{{ event.name }}</h2>
<p>{{ event.location }}</p>
...
</div>
// pagination with buttons and numbers
<div>
<ul>
<li>
<button type="button" v-if="page != 1" @click="page--"> Previous </button>
</li>
<li>
<button type="button" v-for="pageNumber in pages.slice(page - 1, page + 5)" :key="pageNumber"
@click="page = pageNumber"> {{ pageNumber }} </button>
</li>
<li>
<button type="button" @click="page++" v-if="page < pages.length"> Next </button>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "List",
data() {
return {
posts: [],
page: this.$store.state.page,
perPage: this.$store.state.limit,
pages: [],
}
},
mounted() {
this.$store.dispatch("fetchEvents")
},
methods: {
getPosts() {
let events = this.$store.state.events;
for (let i = 0; i < events.length; i++) {
this.posts.push(events[i])
}
},
setPages() {
let numberOfPages = Math.ceil(this.posts.length / this.perPage);
for (let index = 1; index <= numberOfPages; index++) {
this.pages.push(index);
}
},
paginate(posts) {
let page = this.page;
let perPage = this.perPage;
let from = (page * perPage) - perPage;
let to = (page * perPage);
return posts.slice(from, to);
}
},
computed: {
displayedPosts() {
return this.paginate(this.posts);
}
},
watch: {
posts() {
this.setPages();
}
},
created() {
this.getPosts();
},
filters: {
trimWords(value) {
return value.split(" ").splice(0, 20).join(" ") + '...';
}
}
}
</script>
您没有正确更新 Vuex 存储中的
page
和 limit
。您正在尝试使用错误的数据提交突变。 limit
和 page
不是 liveEvents.data
对象的一部分,它们是您在查询中发送的变量的一部分。
您没有查看 Vuex 存储中
events
状态的变化。这意味着当 events
状态发生变化时,您的组件不会对这些变化做出反应。
您正在
posts
函数中初始化 data
,然后在 getPosts
方法中推送到它。这不是响应式的,Vue 将无法跟踪 posts
的更改。
以下是解决这些问题的方法:
fetchEvents
操作以提交正确的 limit
和 page
:actions: {
async fetchEvents({ commit, state }) {
// ...
commit('allEvents', response.data.liveEvents.data);
commit("limit", state.limit),
commit("page", state.page)
// ...
},
}
events
状态,并在其更改时更新 posts
:watch: {
'$store.state.events': {
handler: function(events) {
this.posts = events;
},
immediate: true,
},
posts() {
this.setPages();
}
},
删除
getPosts
方法和 created
生命周期挂钩,因为不再需要它们。
在 Vuex 存储中将
page
初始化为 1 而不是 0:
state: {
limit: 12,
page: 1,
events: [],
},
paginate
方法来处理page
为0时的情况:paginate(posts) {
let page = this.page;
let perPage = this.perPage;
let from = (page * perPage) - perPage;
let to = (page * perPage);
return page > 0 ? posts.slice(from, to) : [];
}
v-if
条件以检查 page
是否大于 1:<button type="button" v-if="page > 1" @click="page--"> Previous </button>
完成这些更改后,您的分页应该可以正常工作。