Reputation: 10422
I'm building a vue2 component, with a vuex store
object. The component looks like this:
<template>
<ul id="display">
<li v-for="item in sourceData()">
{{item.id}}
</li>
</ul>
</template>
<script>
export default {
mounted: function () {
console.log('mounted')
},
computed: {
sourceData: function() {
return this.$store.getters.visibleSource
}
}
}
</script>
The store is populated via an ajax call at the beginning of the process, in the main javascript entry:
new Vue({
store,
el: '#app',
mounted: function() {
this.$http.get('/map/' + this.source_key + '/' + this.destination_key)
.then(function (response) {
store.commit('populate', response.data)
})
.catch(function (error) {
console.dir(error);
});
}
});
I'm not seeing any errors, and when I use the Vue devtools explorer I can see that my component's sourceData
attribute is populated with hundreds of items. I'd expect that once this data is populated, I'd see a bunch of li
rows with item.id
in them appear on the page.
But despite no errors and apparently good data in the component, I am not seeing the template render anything.
Do I need to use some sort of callback to fire the component after the vuex store is populated?
EDIT: adding store code:
import Vue from 'vue';
import Vuex from 'vuex';
import { getSource, getDestination } from './getters'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
field_source: [],
field_destination: []
},
getters: {
visibleSource: state => {
// this just does some formatting
return getSource(state.field_source)
},
visibleDestination: state => {
return getDestination(state.field_destination)
}
},
mutations: {
populate(state, data) {
state.field_source = data.source
state.field_destination = data.destination
}
}
})
EDIT2: Maybe it's not a problem with the v-for
-- I don't see anything from the template being rendered, not even the main ul
tag, which I'd expect to see (empty) even if there was a problem further in the script.
Upvotes: 1
Views: 3223
Reputation: 135862
sourceData
is a computed property, not a method. You don't need to invoke it. Don't use it like v-for="item in sourceData()"
, use it like v-for="item in sourceData"
.
Other than that, on your 'populate'
mutation you are overwritting the observed/reactive objects.
Either use Vue.set()
:
mutations: {
populate(state, data) {
// was state.field_source = data.source
Vue.set(state, 'field_source', data.source);
// was state.field_destination = data.destination
Vue.set(state, 'field_destination', data.destination);
}
}
Or push all elements to the existing, observed/reactive, arrays:
mutations: {
populate(state, data) {
// was state.field_source = data.source
state.field_source.push(...data.source);
// was state.field_destination = data.destination
state.field_destination.push(...data.destination);
}
}
Upvotes: 1