Setting data in state not working in Vue 3 with Vuex 4
Asked Answered
W

2

5

I'm learning Vue 3 with Vuex 4 and I'm stucked with something that I'm pretty sure it's simple but I can't see.

In few words, i'm trying to set some data in state to have it available to use it in my components but it isn't working.

Let me show you the code:

/// store.js

import { createStore } from 'vuex';
import axios from 'axios';

const store = createStore({
  state: {
    user: {},
    products: []
  },
  mutations: {
    SET_USER: (state, user) => {
      state.user = user;
    },
    SET_PRODUCTS: (state, products) => {
      state.products = products;
    },
  },
  actions: {
    GET_USER: async function ({ commit }) {
      const user = await axios.get('https://coding-challenge-api.aerolab.co/user/me')
      commit('SET_USER', user)
    },
    GET_PRODUCTS: async function ({ commit }) {
      const products = await axios.get('https://coding-challenge-api.aerolab.co/products')
      commit('SET_PRODUCTS', products)
    },
  }
})

export default store;

/// MyComponent.vue

<template>
  <div class='bg-aerolab-main'>
    {{ user }} {{ productsTest }}
  </div>
</template>

import { computed } from "vue";
import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore();
    const user = computed(() => store.state.user);
    const productsTest = computed(() => store.state.products);
    console.log(user);
    console.log(productsTest);

    return {
      user,
      productsTest
    };
  }
}

/// main.js

import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import axios from 'axios'
import VueAxios from 'vue-axios';
import store from './store';

const app = createApp(App)
  app.use(VueAxios, axios)
  app.use(store)
  app.mount('#app')

Of course the {{ users }} and {{ productsTest }} bindings are not displaying any data aswell as both console.logs.

PD: I've tried to fetch the data directly in my component and it's working so it's not something related to the data fetched from the API.

Weft answered 28/3, 2021 at 20:11 Comment(0)
A
4

You've to dispatch that actions inside mounted hook :

import { computed , onMounted} from "vue";
import { useStore } from 'vuex';

export default{
  setup() {
    const store = useStore();
    const user = computed(() => store.state.user);
    const productsTest = computed(() => store.state.products);
   
  onMounted(()=>{
    store.dispatch('GET_USER');
    store.dispatch('GET_PRODUCTS');
  })
    return {
      user,
      productsTest
    };
  }
}
Avie answered 28/3, 2021 at 20:16 Comment(0)
R
2

Fetch Data from main.js

I'm sure the selected answer would work properly if you are fetching data from your component(s). However, if you are looking to Fetch Data from main.js as OP was asking or app.js if you are using Vue3 with Laravel, you should use mounted() in your createApp() function.

const app = createApp({
    mounted(){
        store.dispatch('YOUR_ACTION') // GET_USER or GET_PRODUCTS in OP's case
    }
});

Remember to set up your Vuex store before calling this so the store is defined.

In your components

You can access the computed state with composition API, as shown below:


import { computed } from "vue";
import { useStore } from "vuex";

setup() {
        const store = useStore();
       
        return {
            products: computed(() => store.state.YOUR_STATE), 
            //replace YOUR_STATE with your own. In OP's case, it's user or products
        };
    }
Ravens answered 11/6, 2021 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.