Reputation: 187
I've inherited a VueJs project written in typescript. I have a component which is displaying some data, the vuex store is updated via a mutation (ADD_SCHOOL) but the changes are not reflected in the view. I'm guessing that i need some sort of watcher but i'm not sure what i need to do so that Vue reacts to the change in my Store.
View
data() {
return {
school: {} as ISchool
};
},
async mounted() {
await this.getSchoolInformation();
},
methods: {
async getSchoolInformation() {
this.school = await Stores.schoolStore.getSchool(1);
}}}
Store.ts
Vue.use(Vuex);
const modules: ModuleTree<IRootState> = {
schoolStore: schoolModule
};
const store: Store<IRootState> = new Store<IRootState>({
modules
});
export default store;
SchoolStore.ts
export default class SchoolStore {
public async getSchool(id: number, isFirstLoad: boolean): Promise<ISchool> {
return Store.getters[SchoolNamespace + GetterTypes.GET_SCHOOL_FROM_STORE];
}
}
School Modules.ts
export const state: ISchoolState = {
schools: []
};
export const getters: GetterTree<ISchoolState, IRootState> = {
[GetterTypes.GET_SCHOOL_FROM_STORE]: state => {
const storeSchool: ISchool | undefined = state.schools.find(x => x.id === 1);
return storeSchool as ISchool;
}
};
export const mutations: MutationTree<ISchoolState> = {
[MutationTypes.ADD_SCHOOL](state: ISchoolState, school: ISchool): void {
const index: number = state.schools.findIndex(x => x.id === school.id);
if(index === -1) {
state.schools.push(school);
} else {
state.schools.splice(index, 1, school);
}}};
const schoolModule: Module<ISchoolState, IRootState> = {
actions,
getters,
mutations,
namespaced: true,
state
};
export default schoolModule;
Index.ts
const schoolStore: SchoolStore = new SchoolStore();
export default {
schoolStore
};
Upvotes: 3
Views: 2892
Reputation: 4220
This problem you are having is described in the docs: reactivity in depth
On your mutation you're updating an item in the array or adding a new item to the array. Vue will not pick up that change. For that to work you need to user Vue.set
:
import Vue from 'vue'
...
if(index === -1) {
Vue.set(state.schools, state.schools.length, school);
} else {
Vue.set(state.schools, index, school);
}}};
Upvotes: 2
Reputation: 187
Thanks to Ackroydd i manged to get his working by simplying using a computed property in my View - I also made getSchool synchronous
Updated View
computed: {
school() {
return Stores.schoolStore.getSchool(1, false);
}
}
});
Upvotes: 2