I have a component that lists entries of an array of posts
(it’s stored as projects in the store). When created the component dispatches a action to the store that fetches the data and mutates the resulting data into the state. Which works fine and the component shows the computed property of posts
as populated (in Vue panel), but the template refuses to re-render its content.
Component
<template>
[...]
<CardGrid v-if="posts.length">
<Card
v-for="post in posts"
:key="post.id"
:type="post.projekttype"
:title="post.projekttitle"
:content="post.description"
/>
</CardGrid>
[...]
</template>
<script>
import { mapGetters } from 'vuex';
import Card from '@/components/Theme/Card.vue';
import CardGrid from '@/components/Theme/CardGrid.vue';
import utils from '@/utils/utils';
export default {
name: 'Grid',
moduleScheme: {
[...]
settings: {
dataSource: 'project',
}
},
components: {
Card,
CardGrid
},
props: {
moduleId: {
type: String,
required: true
}
},
computed: {
...mapGetters([
'getPosts',
'getCurrentPageModule',
]),
moduleSettings: function () {
return this.getCurrentPageModule(this.moduleId).settings;
},
posts: function () {
return Array.from(this.getPosts(this.moduleSettings.dataSource));
},
},
methods: {
loadData: async function () {
this.$store.dispatch('loadData', {
dataSource: this.moduleSettings.dataSource,
});
},
},
created () {
this.loadData();
}
}
</script>
Store
import Vue from 'vue';
import { posts } from '@/utils/fetch';
import router from '@/router';
const store = {
state: {
[...]
allPosts: {
[...]
project: [],
},
},
mutations: {
mutateAllPosts(state, payload) {
Vue.set(state.allPosts, payload.dataSource, [...payload.posts]);
},
[...]
},
getters: {
getPosts: (state) => (dataSource) => state.allPosts[dataSource],
[...]
},
actions: {
[...]
loadData: async ({ commit }, settings) => {
if (settings.dataSource === 'project') {
const filter = {
[...]
}
const response = await posts.get.all(settings.dataSource, filter);
commit('mutateAllPosts', {
posts: response,
dataSource: settings.dataSource
});
} else {
const response = await posts.get.all(settings.dataSource);
commit('mutateAllPosts', {
posts: response,
dataSource: settings.dataSource
});
}
},
[...]
}
export default store;
Populated posts property
I tried replacing the mapGetter and use the state directly resp. using VueX’s mapState helper.
...mapState({
posts (state) {
return state.posts.allPosts;
}
}),
This led to the data showing up in the component. But as soon as I tried filtering for it, by adding moduleSettings.dataSource
it disappears again. Since I’d like to just get the project
array from the state I thought it would be better to call it via an getter with included filter.
I suspect I got any misconception of vue’s reactivity model anywhere but can’t find it.