Mutating state in vuex - vue.js

I'm trying to make an api call to my DB and commit the mutation but i'm not having much success.
Store.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
photons: [],
},
mutations: {
setData(state, value) {
console.log(value)
state.photons = value
}
},
actions: {
async getData(context) {
const data = await axios.get('10.10.10.1:3000/DB')
console.log(data)
context.commit('setData', data)
},
} })

In your main.js try to dispatch that action in mounted hook :
import Vuex from 'vuex';
import store from './vuex/store';
const app = new Vue({
el: '#app',
store,
mounted() {
this.$store.dispatch('getData')
}
});

Related

Vue3 - Persisting state with Page refresh

I have just started using Vue3, and am trying to use vuex to manage state. when using Vue2 I would call the store each time the app loads like this:
// mains.js
import VueRouter from "vue-router";
import Vuex from "vuex";
import router from "./routes";
window.Vue = require('vue').default;
Vue.use(VueRouter);
Vue.use(VueMoment);
Vue.use(Vuex);
const store = new Vuex.Store(storeDefinition);
const app = new Vue({
el: '#app',
router,
store,
components: {
"index": Index
},
async created() {
this.$store.dispatch("loadStoredState");
this.$store.dispatch("loadUser");
},
});
This is my vuex store that defines state, mutations and actions for vuex:
// store.js
import { isLoggedIn, logOut } from "./shared/utils/auth";
export default {
state: {
isLoggedIn: false,
user: {}
},
mutations: {
setUser(state, payload) {
state.user = payload;
},
setLoggedIn(state, payload) {
state.isLoggedIn = payload;
}
},
actions: {
loadStoredState(context) {
context.commit("setLoggedIn", isLoggedIn());
},
async loadUser({ commit, dispatch }) {
if (isLoggedIn()) {
try {
const user = (await axios.get("/user")).data;
commit("setUser", user);
commit("setLoggedIn", true);
} catch (error) {
dispatch("logout");
}
}
},
logout({ commit }) {
commit("setUser", {});
commit("setLoggedIn", false);
logOut();
}
},
getters: {}
}
This file manages a cookie for local storage that stores a boolean value for isLoggedIn:
// auth.js
export function isLoggedIn() {
return localStorage.getItem("isLoggedIn") == 'true';
}
export function logIn() {
localStorage.setItem("isLoggedIn", true);
}
export function logOut() {
localStorage.setItem("isLoggedIn", false);
}
But in Vue3 I am creating the main.js file like this:
// mains.js
const { createApp } = require('vue')
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from "./store";
const store = createStore(storeDefinition)
createApp(Index)
.use(createRouter())
.use(store)
.mount('#app')
How can I add the two calls to manage the store to the createApp function?
You can add the created hook to the root component by using the extends option with the component definition:
// main.js
import { createApp } from 'vue'
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from './store'
const store = createStore(storeDefinition)
createApp({
extends: Index,
created() {
this.$store.dispatch('loadStoredState')
this.$store.dispatch('loadUser')
},
})
.use(createRouter())
.use(store)
.mount('#app')
demo

Why Vue doesn't see vuex?

I work with microfrontend single-spa (https://single-spa.js.org/)
I create a store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
}
})
in src/main.js i import it
import Vue from 'vue';
import singleSpaVue from 'single-spa-vue';
import 'devextreme/dist/css/dx.light.css';
import App from './App.vue';
import store from './store';
console.log("πŸš€ ~ file: main.js ~ line 6 ~ store", store)
Vue.config.productionTip = false;
Vue.prototype.$bus = new Vue();
const vueLifecycles = singleSpaVue({
store,
Vue,
appOptions: {
render(h) {
return h(App, {
store,
props: {
},
});
},
},
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
in console.log store displayed, but in the app cnsole.log(this) does not contain store
I don't understand where I am connecting wrong?
According to the docs, store should be a subproperty of appOptions:
const vueLifecycles = singleSpaVue({
// store, ❌
Vue,
appOptions: {
store, βœ…
render(h) {
return h(App, {
// store, ❌
props: {},
})
},
},
})

Uncaught ReferenceError: photoModule is not defined

Uncaught ReferenceError: photoModule is not defined
Π•he first time I encountered such an error so that the vuex store does not find the module.
What could be the problem?
vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
photoModule
}
})
main.js
import store from './store'
Vue.prototype.axios = axios
Vue.config.productionTip = false
new Vue({
vuetify,
router,
store,
render: h => h(App)
}).$mount('#app')
photoModule
import axios from 'axios'
export default {
state: {
photos: []
},
mitations: {
setPhotos(state, payload) {
state.photos = payload
}
},
getters: {
getAllPhotos(state) {
return state.photos
}
},
actions: {
fetchPhotos(context) {
axios.get('https://jsonplaceholder.typicode.com/photos?_limit=10')
.then(response => this.photos = context.commit('setPhotos', response.data))
}
}
}
For the second day I have been sitting on this error. At least hint where something is wrong
You didn't import the module
import Vue from 'vue'
import Vuex from 'vuex'
import photoModule from './photoModule.js' // βœ… Add this
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
photoModule
}
})

How can I access the router id in vuex store and to append it to Axios get method

Hi I am trying to get the id from router and to append it to axios get method.
This is the code from store.js
In normal Vue component you can do something like this: id:this.$router.id
but in vuex store is not working
#How can I do the same thing but in Vuex
import Vue from 'vue'
import Vuex from 'vuex'
import Axios from 'axios';
import router from './router'
Vue.use(Vuex)
Vue.use(Axios)
Vue.use(router)
export default new Vuex.Store({
// data() {
// return {
// m_id:this.$route.params.m_id
// }
// },
// m_id : this.$route.params.m_id,
state: {
video_key: [],
},
mutations: {
updateInfo (state , video_key){
state.video_key = video_key
}
},
getters:{
m_id : this.route.params.m_id
},
actions: {
fetchData({commit,getters}){
axios.get(`https://api.themoviedb.org/3/movie/${this.m_id}/videos?api_key=7bc75e1ed95b84e912176b719cdeeff9&language=en-US`)
.then(response =>{
commit('updateInfo',response.data.results[0].key)
})
}
}
})
Replace this.route.params.m_id with router.currentRoute.params.m_id.
You can find more details about router instance properties here: link

How can I fix '[vuex] unknown action type: lookupName' within my Vue component?

I am having an issue calling up an action from my Vue component using this.$store.dispatch('lookupName'). I have tried console logging the this.$store method, but the actions within it are empty.
Main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { findCertificate } from '#/api';
Vue.use(Vuex)
const state = {
// single source of data
nameLookup: {},
}
const actions = {
// asynchronous operations
lookupName(context, form){
return findCertificate(form)
}
}
const store = new Vuex.Store({
state,
actions,
mutations,
getters
})
export default store
Vue Component
import VueRecaptcha from 'vue-recaptcha';
import { mapGetters, mapActions} from 'vuex'
export default {
created() {
},
methods: {
...mapActions({
lookupName: 'lookupName'
}),
...mapActions({
add: 'lookupName'
}),
onCaptchaVerified: function(recaptchaToken){
this.$refs.recaptcha.reset();
console.log(this.$store.dispatch('lookupName', this.form))
},
}
}
Why am I still getting this error? I have looked up many other people's questions about similar issues, but those solutions did not work for me.