I have a child component (<BaseProjectTable>
) that is re-used throughout my site that contains a Vuetify <v-data-table>
component. The headers and content items for the data table are passed into the the component as props, and the item data is mapped into the parent as a mapGetter
from a Vuex store. The child component contains editing functionality for each row, and I'm using a mapAction
to update the API and Vuex data from there, with the idea being that since my mapGetter is reactive, it should update the data and hence the data table display. However, this is not working; I can see via dev tools that state is updated just fine, but the child component display is not.
Here is the relevant portion of the child <BaseProjectTable>
component:
<template>
<div>
<v-data-table
show-expand
:headers="headers"
:items="filteredItems"
:search="search"
tem-key="sow"
@click:row="rowClick"
:hide-default-footer="disablePagination"
dense
:disable-pagination="disablePagination"
>
...
</v-data-table>
...
export default {
name: "BaseProjectTable",
props: {
headers: Array,
items: Array,
loggedInUser: Object,
title: String,
max2chars: v => v.length <= 2 || 'Input too long!',
editDialog: false,
showPracticeFilter: {
default: true,
type: Boolean
},
showSEFilter: {
default: true,
type: Boolean
},
showStatusFilter: {
default: true,
type: Boolean
},
projectType: {
type: String,
default: 'active'
},
disablePagination: {
type: Boolean,
default: true
},
},
},
methods: {
...mapActions('projects', {
saveProject: 'saveProject',
}),
save() {
// Update API and store with new data.
this.saveProject({
projectType: this.projectType,
projectData: this.editedItem
})
},
computed: {
statuses() {
return this.projectType === 'active' ? this.activeStatuses : this.oppStatuses;
},
filteredItems() {
return this.items.filter(d => {
return Object.keys(this.filters).every(f => {
return this.filters[f].length < 1 || this.filters[f].includes(d[f])
})
})
},
}
and here is the relevant code from the parent component:
<v-card>
<BaseProjectTable
:headers="headers"
:items="activeProjects"
:loggedInUser="loggedInUser"
title="Active Projects"
:disablePagination=false
></BaseProjectTable>
</v-card>
...
export default {
computed: {
...mapGetters('projects', {
activeProjects: 'activeProjects',
closedProjects: 'closedProjects',
opportunities: 'opportunities'
}),
}
}
The save()
method updates the data in my Vuex store that is referenced by the activeProjects
map getter (I have verified in the Vue devtools that this is true). It also shows the items
value in the component itself updated in the Components
tab in the dev tools. Since using mapGetters
makes the data reactive, I expected that it would also update the data in my child component, but it doesn't.
Based on what I saw here, I tried the item-key
property of the <v-data-table>
like so:
<v-data-table
show-expand
:headers="headers"
:items="filteredItems"
:search="search"
item-key="sow"
@click:row="rowClick"
:hide-default-footer="disablePagination"
dense
:disable-pagination="disablePagination"
>
(every record using this component will have the unique sow
key), but that didn't work.
The only think I could think if is how I'm editing the data in my mutation:
export const state = () => ({
active: [],
closed: [],
opportunities: [],
})
export const getters = {
activeProjects: state => state.active,
closedProjects: state => state.closed,
opportunities: state => state.opportunities,
}
export const actions = {
saveProject({ commit }, {projectType, projectData}) {
commit(types.SAVE_PROJECT, {projectType, projectData});
}
}
export const mutations = {
[types.SAVE_PROJECT](state, {projectType, projectData}) {
// Get project from state list by sow field.
const index = state[projectType].findIndex(p => p.sow === projectData.sow);
state[projectType][index] = projectData;
}
}
as compared to replacing the entire state[projectType]
value.
What do I need to do to get the data table to display my updated value?
active
in store the same asactiveProjects
? Could not correlate the mutation - I may have missed something there. Did you try replacingstate[projectType][index] = projectData;
withthis.$set(state[projectType], index, projectData)
- that should ensure reactivity and reflect changes in getter. – Prashanth K