I am making a spa app with laravel and vue, and I would like to keep my login information in vuex's state after refreshing a page.
I typed
sudo npm install vuex-persistedstate
and installed Vuex-persistedstate and set the plugins as below.
import Vue from 'vue' import Vuex from 'vuex'
import auth from './auth'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
auth,
plugins: [createPersistedState()],
}
})
export default store
I expected my data to be kept after refreshing a page but it was not.
I checked what is going on, and it seems the plugin object was empty.
it seems that I cannot import the plugins for some reason, but I do not know why.
Could someone help me, please?
my module file
const state = {
user: null,
salonId: null
}
const getters = {
check: state => !! state.user,
checkSalonId: state => {return state.salonId},
}
const mutations = {
setUser (state, user) {
state.user = user
},
setSalonId (state, salonId) {
state.salonId = salonId
}
}
const actions = {
async currentUser (context) {
const response = await axios.get('/api/user')
const user = response.data || null
context.commit('setUser', user)
},
async logout (context) {
context.commit('setUser', null)
context.commit('setSalonId', null)
},
async currentSalon (context, salonId) {
context.commit('setSalonId', salonId)
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions,
}
You placed plugins in the wrong place. plugins should be inline with modules, not inside modules.
Please take a look at this differences.
const store = new Vuex.Store({
modules: {
auth,
plugins: [createPersistedState()]
}
})
VS
const store = new Vuex.Store({
modules: {
auth
},
plugins: [createPersistedState()]
})
I think you need to setup an option object with the modules you wanna persist. In this example i'm persisting the user module from my store (haven't include the import code)
const persistedStateOptions = {
paths: [
'user',
]
}
export default new Vuex.Store({
modules: {
user,
},
plugins: [createPersistedState(persistedStateOptions)]
})
Look at difference in paths.This worked for me.
import createPersistedState from 'vuex-persistedstate';
Vue.use(Vuex);
export default new Vuex.Store({
strict:true,
modules:{
party,
contract
},
plugins: [createPersistedState(
{
paths:['party.selectedParty']
}
)],
});
Where party is the module name and selectedParty is the name of module state.
Now this plugin only taking care of selectedParty state.
The vue components that get data via state from DB should be kept out of this plugin.
Related
I am working on a project using vue and vuex. And I think most of the people are having the problem, after sometime the store.js (or index.js) is getting too big. So I want to split the store.js file. After some google I found I can use Modules to overcome this problem. BUT I tried also with creating a new Instance of vuex and it works perfectly fine.
Single instance with modules :
---store.js
import Vuex from "vuex";
import thisismodule1 from "./modules/module1";
import thisismodule2 from "./modules/module2";
const createStore = () => {
return new Vuex.Store({
modules: {
module1: thisismodule1,
module2: thisismodule2
}
});
};
export default createStore;
const store = new Vuex.Store({
module
});
Multiple files with multiple instances:
---storeCar.js
---storeHouse.js
---storeTree.js
...
So my question is, is this allowed or do I have to use modules with single instance?
Thank you in advance!
there is a best practice for that:
Create a file. that's name is Shared
Create a Store folder and create a modules folder on it:
you should modules in the modules folder and define your store for a target:
for example:
import * as types from "../types";
const state = {
currentPage: {}
};
const getters = {
[types.avatarManagement.getters.AVATAR_MANAGEMENT_GET]: state => {
return state.currentPage;
}
};
const mutations = {
[types.avatarManagement.mutations.AVATAR_MANAGEMENT_MUTATE]: (
state,
payload
) => {
state.currentPage = payload;
}
};
const actions = {
[types.avatarManagement.actions.AVATAR_MANAGEMENT_ACTION]: (
{ commit },
payload
) => {
commit(types.avatarManagement.mutations.AVATAR_MANAGEMENT_MUTATE, payload);
}
};
export default {
state,
getters,
mutations,
actions
};
Create index.js for define Vuex and import your modules:
index.js file:
import Vue from "vue";
import Vuex from "vuex";
import avatarManagement from "./modules/avatarManagement";
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
avatarManagement
}
});
5) also you can types of your vuex store on Type.js file:
type.js:
export const avatarManagement = {
getters: {
AVATAR_MANAGEMENT_GET: "AVATAR_MANAGEMENT_GET"
},
mutations: {
AVATAR_MANAGEMENT_MUTATE: "AVATAR_MANAGEMENT_MUTATE"
},
actions: {
AVATAR_MANAGEMENT_ACTION: "AVATAR_MANAGEMENT_ACTION"
}
};
***for get data from Store:
computed: {
...mapGetters({
registrationData:types.avatarManagement.AVATAR_MANAGEMENT_GET,
getDataFromStore() {
return this.registrationData;
}
}
***for Change data to Store and mutate that:
methods: {
goToActivity() {
const activity = {
companyList: this.categories
};
this.$store.commit(types.avatarManagement.AVATAR_MANAGEMENT_MUTATE, {
newData
});
},
}
I tried this but only got an error message
This relative module was not found:
* ./router in ./store/index.js
// Ran with yarn dev
import router from './router'
export const state = () => ({
authenticated: false,
})
export const mutations = {
toggleLogin(state, loginStatus, path) {
state.authenticated = loginStatus
if (loginStatus) {
router.push(path)
} else {
router.push('login')
}
},
}
My store path is store/index.js
Vuex mutations and getters doesn't have access to the Vue context. Only actions does.
Also, you can't import the Nuxt router like that. What's that file you're trying to import?
I'd suggest to make an action instead:
export const actions: {
toggleLogin({ commit }, payload) {
this.app.router.push('') //exists
}
}
I am using nuxt.js with the auth module.
Every time i open a new page on my profile this error message appears.
I have created a mixin called auth.js in my plugins/mixins directory. This file contains the code:
export const getters = {
authenticated(state) {
return state.loggedIn;
},
user(state){
return state.user;
}
};
I've created a getter file called auth.js with the following code:
import Vue from 'vue'
import {mapGetters} from 'vuex'
const User = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
user: 'auth/user',
authenticated: 'auth/authenticated'
})
}
})
}
};
Vue.use(User);
The getters and mixin work, but everytime i open a page it gives me this error and i dont know how to solve it. I've tried the solutions in this question:
duplicate namespace auth/ for the namespaced module auth
Altough this does solve the errors, it makes my getters undefined.
Yeah, I found a workable way ...
Switch to index.js auth.js logic, and delete auth.js.
index.js
export const getters = {
authenticated(state) {
return state.auth.loggedIn
},
user(state) {
return state.auth.user
}
}
Revise it as follows if you are using a user.js mixin:
import Vue from 'vue'
import {mapGetters} from 'vuex'
const User = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
user: 'user',
authenticated: 'authenticated'
})
}
})
}
};
Vue.use(User);
Plugins:
** Plugins to load before mounting the App
*/
plugins: ["./plugins/mixins/user.js"
],
I'm trying to implement Vuex store in a Quasar project. I created a new project using the quasar-cli and checked the Vuex box. I then followed the guide on the quasar website (https://quasar.dev/quasar-cli/cli-documentation/vuex-store)
and created a new store using quasar new store test
I then registered the store module in the store/index.js
export default function(/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
test
// example
},
Afterwards, I added the mutation and state code, exactly as referenced in the tutorial.
Then I created a new component (test) and added the code as explained.
However, I am unable to use this.$store, and receive a warning from my IDE that $store is not defined.
I have read the Vuex documentation, which writes that it is possible to pass the state to all components by adding the state to the object in main.js. As far as i can see, quasar does this already.
So, what am I doing wrong and how can you use store without manually importing it for every single component?
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
// general state
app
},
mutations: {
someMutation (state, store) {
}
},
actions: {
someAction ({commit}) {
},
})
export default store
Also don't forget to include this store in app.js
Vue.use(Vuex) was missing
Vuex provides a mechanism to "inject" the store into all child components from the root component with the store option (enabled by Vue.use(Vuex))
It took me a while to get it working but here is an example of my state
user :
{
uid: '',
name: '',
accountType: ''
}
}
const mutations = {
setName (state, val) {
state.user.name = val
},
setUID (state, val) {
state.user.uid = val
},
setAccountType (state, val) {
state.user.accountType = val
}
}
const actions = {
}
const getters = {
user: (state) => {
return state.user
}
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
then in each file if you want to access this information you have to use
computed : {
user () {
return this.$store.getters['user/user']
}
}
I wanted to display this information in my tags and can do so with
<template>
<div class="user-profile">
{{ user.name }}
{{ user.email }}
{{ user.accountType }}
</div>
</template>
hope that helps.
note rather than a folder with my modules I have it all in one file 'store-user.js' and in my store/index.js I have
import user from './store-user'
and
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
user
}
// enable strict mode (adds overhead!)
// for dev mode only
strict: process.env.DEV
})
return Store
}
Humbly, I admit that I'm gleaning from SAVuegram in setting up authentication for my app. I am running Firebase's onAuthStateChanged to make certain the user stays logged in during page refreshes however I am completely unable to access the state inside of the function, receiving the following error.
(the $store is just from me taking a screenshot while testing "$store" as well as "store" - both break.)
With strict debugging turned on I'm also getting messages warning me about mutating outside of mutation handlers, but isn't that what I'm doing?
Here's my store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import fb from '../components/firebase/firebaseInit'
import createLogger from 'vuex/dist/logger'
// import dataRefs from './dataRefs'
// import pageTitle from './modules/pageTitle'
import auth from './modules/auth'
import apps from './modules/applicants'
Vue.use(Vuex)
fb.auth.onAuthStateChanged(user => {
if (user) {
// here I can access the user object but never the following "store"
console.log("FB AUTH", user);
store.commit('setCurrentUser', user)
store.dispatch('fetchUserProfile')
}
});
const debug = process.env.NODE_ENV !== 'production'
const createStore = () => {
return new Vuex.Store({
state: {
pageTitle: '',
currentUser: null,
userProfile: null
},
mutations: {
changePageTitle(state, newTitle) {
state.pageTitle = newTitle
},
changeSnackBarMessage(state, newMessage) {
state.snackBarMessage = newMessage
},
// POPUPS
changeAdvisorAddAppPopupStatus(state) {
state.showAdvisorAddPopup = !state.showAdvisorAddPopup
},
setToken(state, token) {
state.token = token;
},
setUser(state, userObj) {
state.user.email = userObj.email;
state.user.fbUUID = userObj.uuid;
}
},
actions: {
updatePageTitle(vuexContext, newTitle) {
vuexContext.commit('changePageTitle', newTitle);
},
updateSnackBarMessage(vuexContext, newMessage) {
vuexContext.commit('changeSnackBarMessage', newMessage);
},
toggleAdvisorAddPopup(vuexContext) {
vuexContext.changeAdvisorAddAppPopupStatus
},
},
modules: {
auth,
apps
},
strict: debug,
plugins: debug ? [createLogger()] : []
})
};
export default createStore;
FYI, I have also tried to instantiate my store by using export const store = new Vuex.Store({ instead of the const create ... method but then Vuex show me that none of my state, actions, getters, or mutations are even found.
Thanks for the help.
Why do you create the store in a function?
const createStore = () => {
I am just doing it like that:
const store = new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {
auth,
apps
},
strict: debug,
plugins: debug ? [createLogger()] : []
})
};
export default store;
And i am able to access store now.