Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting data in state not working in Vue 3 with Vuex 4

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.

like image 980
Franco Alemandi Avatar asked Mar 28 '21 20:03

Franco Alemandi


People also ask

Does Vuex work with Vue 3?

The short answer is: Yes. Vuex is the preferred state management solution for Vue apps, and Vuex 4 is the version compatible with Vue 3. Do take note, however, that using Vuex for state management depends on the complexity of your application.

Why you might not need Vuex with Vue 3?

Why would anyone leave Vuex? The reason could be that the upcoming Vue 3 release exposes the underlying reactivity system and introduces new ways of structuring your application. The new reactivity system is so powerful that it can be used for centralized state management.

How do I add Vuex to Vue 3?

Adding Vuex to your Vue 3 Projectimport { createApp } from "vue";import { createStore } from "vuex";// Create a new store instance or import from module. const store = createStore({ /* state, actions, mutations */});const app = createApp();app. use(store);app. mount("#app");


Video Answer


2 Answers

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
    };
  }
}
like image 156
Boussadjra Brahim Avatar answered Oct 22 '22 16:10

Boussadjra Brahim


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
        };
    }
like image 32
Andre W. Avatar answered Oct 22 '22 16:10

Andre W.