vuex store doesn't update component
Asked Answered
T

5

25

I'm new to vue, so I'm probably making a rookie error.

I have a root vue element - raptor.js:

const Component = {
el: '#app',
store,
data: {
    productList: store.state.productlist
},
beforeCreate: function () {
    return store.dispatch('getProductList', 'getTrendingBrands');
},
updated: function (){
    console.log(111);
    startSlider();
}
};
const vm = new Vue(Component);

Using this template

<div class="grid-module-single popular-products" id="app">
<div class="row">
    <div class="popular-items-slick col-xs-12">
        <div v-for="product in productList">
            ...
        </div>
    </div>
</div>

My store is very simple store/index.js:

import Vue from 'vue';
import Vuex from 'vuex';
import model from '../../utilities/model';

Vue.use(Vuex);

export default new Vuex.Store({
state: {
    productlist: []
},
mutations: {
    setProductList(state, data) {
        state.productlist = data;
    }
},
actions: {
    getProductList({ commit }, action) {
        return model.products().then(data => commit('setProductList', data));
    }
}
});

In my vuex devtool, I can see, that the store is being updated https://www.screencast.com/t/UGbw7JyHS3

but my component is not being updated: https://www.screencast.com/t/KhXQrePEd

Question:

I can see from the devtools, that my code is working. The store is being updated with data. My component is not being updated,however. I thought it was enough just to add this in the data property on the component:

data: {
    productList: store.state.productlist
}

but apparently the data object doesn't seem to be automatically synced with the store. So either I'm doing a complete vue no-no somewhere, or I need to tweak the code a bit. Anyway can anyone help me in the right direction.

Thanks a lot.

Tripper answered 12/2, 2017 at 20:28 Comment(0)
T
37

UPDATE

Figured it out myself. Just had to replace the components data part with a computed method:

data:

data: {
  productList: store.state.productlist
}

and replace it with.

computed: {
    productList () {
        return store.state.productlist;
    }
},
Tripper answered 12/2, 2017 at 21:39 Comment(6)
Is this way documented?Stolid
Yes, I found the solution in the documentation: vuex.vuejs.org/en/state.htmlTripper
Is it necessary to replace it? Or can we keep both data and computedMansion
Yes, you can use both like this example from Vue docs: vuejs.org/v2/guide/computed.html. It's used in the example to avoid large expression in {{ }} operator.Collette
I had forgotten to add state between store and productlist. Gratitude @MartinKure!Keli
this worked for me as well const loggedIn = computed(() => store.getters['auth/authenticated']); now updates after the store value gets changed.Foreclose
T
5

data only work once on component before render, so you can use computed instead. like above answer, or you can use mapstate

import {mapState} from 'vuex'
...
computed: mapState({
  productList: state => state.productList
})             
Tractor answered 27/7, 2017 at 2:11 Comment(1)
Now it's mapState with a capital S.Medical
V
4

First - use getter to do this mapGetters, also you need to watch this property somehow, you can set store subscription or just with watch method trough component.

 this.$store.subscribe((mutation, state) => {    
   if (mutation.type === 'UPDATE_DATA') {
      ...
   }
 }
Volant answered 16/3, 2018 at 15:40 Comment(2)
hmm.. interesting. But where do you subscribe to the changes? In the component in mounted()?Leif
proper way is to use it in created() hook, but guess that in mounted will work tooVolant
A
0

For composition API with script setup, i.e., <script setup>, try this.

const productList = computed(() => store.state.productlist);
Agnesse answered 3/6, 2023 at 20:51 Comment(0)
P
-2

You are calling the store into the productList data property in the wrong way.

You can try it:

data: {
  productList: $store.state.productlist
}

Otherwise you have to import store in each component that are using the store.

Plerre answered 30/5, 2020 at 6:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.