import Vue from 'vue'
import Vuex from 'vuex'
import User from './service/User'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
users: [User]
},
getters : {
getUsers(state) {
return state.users;
}
},
mutations: {
addUser(state, user) {
state.users.push(todo);
console.log('Added')
}
},
actions : {
addUser({ commit }, user) {
const result = User.users(user)
commit('addUser', user)
}
}
})
export default store;
Hi all, this is my store.js i was about to get data from my backend using vuex. but it didn't work. i think i might be something doing wrong here.
Thank you in advance for your help. Highly Appreciated.
Related
I made a vuex store:
export const general = {
namespaced: true,
state: {
menuEnabled: true,
headerEnabled: true
},
getters: {
menuState: state => state.menuEnabled,
headerState: state => state.headerEnabled
},
actions: {
setMenuVisibility({commit}, visibility) {
commit('setMenuVisibility', visibility);
},
setHeaderVisibility({commit}, visibility) {
commit('setHeaderVisibility', visibility);
}
},
mutations: {
setMenuVisibility(state, visibility){
state.menuEnabled = visibility;
},
setHeaderVisibility(state, visibility){
state.headerEnabled = visibility;
}
}
}
index.js
import { createStore } from "vuex";
import { auth } from "./auth.module";
import {general} from "./general.module";
const store = createStore({
modules: {
general,
auth
},
});
export default store;
main.js
import router from "./router";
import store from "./store";
createApp(App)
.use(store)
.use(router)
.mount('#app')
After that, I created 2 computed functions in App.vue:
computed: {
menuVisibilityState : function (){
return this.$store.state.menuEnabled;
},
headersVisibilityState : function () {
return this.$store.state.headerEnabled;
}
}
But, I can't get them from vuex:
I tried to import general directly in App.vue and get the values.
It doesn't work and I think, that it's bad way to get them.
Can somebody help me?
When you create a module in Vuex, the local state is nested depending on the name you've provided to the module (this happens when you're accessing the root state.).
In your example, to access the local state of general module you could write:
computed: {
menuVisibilityState : function (){
return this.$store.state.general.menuEnabled;
},
headersVisibilityState : function () {
return this.$store.state.general.headerEnabled;
}
}
Keep in mind that:
actions and mutations are still registered under the global namespace - this allows multiple modules to react to the same action/mutation type. Getters are also registered in the global namespace by default.
https://vuex.vuejs.org/guide/modules.html#namespacing
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 need a data from my store object above in my module, but I cannot access it.
I have a store object
This store object has one or more modules it uses.
I was try it :index.js
import { createStore } from "vuex";
import moduleLayout from "./modules/moduleLayout.js"
export default createStore({
state:{
testData:'Hello World!'
},
modules: { moduleLayout }
})
and have a moduleLayout.js
export default {
state:{
size:100
},
getters:{
getSizeAndText:(state)=>{
return {size:state.size,text:this.state.testData};
//error here, because (this)undefined
//how can i access on here testData
}
}
}
I cannot access testData data from my moduleLayout.js
No need to import index.js.
We can access it by expanding the parameter field.
on "index.js"
import moduleTest from "./modules/moduleTest";
export default{
state:{
size:100
},
modules:{
moduleTest:moduleTest
}
}
on "moduleTest.js"
export default{
state:{
testSize:20
},
getters: {
getSumSize(thisState, getters, state) {
return thisState.testSize+state.size;//this result 120
},
getSumSizeWithParam:(thisState, getters, state) =>(index)=>{
return (thisState.testSize+state.size)*index;//this result 120*index
}
}
}
You definitely don't need to import index.js.
You are not adding the module to the store.
import { createStore } from "vuex";
import moduleLayout from "./modules/moduleLayout.js";
export default createStore({
state: {
testData: 'Hello World!'
},
modules: {
layout: moduleLayout
}
})
Import the store inside module to access the state thats not namespaced by module:
import store from '../index.js'; // whatever the path of where you create and export store
const state = {
size: 100
}
const getters = {
getSizeAndText(state) {
return {
size: state.size,
text: store.state.testData
}
}
}
export default {
state,
getters
}
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.
I'm new to Vuejs and still figuring out how to get the latest updated data.
app.js - preload the data after calling 'global/checkUserSignedIn'
import Vue from 'vue'
import axios from 'axios'
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
import App from 'components/app-root'
import { mapGetters, mapActions } from 'vuex'
Vue.prototype.$http = axios
sync(store, router)
const app = new Vue({
store,
router,
...App,
created() {
this.preload()
},
methods: {
preload: function () {
this.$store.dispatch('global/checkUserSignedIn')
}
}
})
export { app, router, store }
global.js (a vuex store)
/// actions, mutations here
const actions = {
checkUserSignedIn({ commit, state }) {
commonApi.isUserSignedIn().then(function (data) {
state.usersignedin = data
})
},
}
const getters = {
isUserSignedIn: state=>state.usersignedin
}
export default {
state,
getters,
actions,
mutations,
namespaced: true
}
On a component, I call:
export default {
computed: {
...mapGetters('global', ['isUserSignedIn']),
},
watch: {
isUserSignedIn: function (newVal, oldVal) {
if (newVal !== undefined) {
console.log('ok, correct result')
}
}
},
updated() {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
console.log('updated: ' + this.isUserSignedIn)
})
},
created() {
console.log('created :' this.isUserSignedIn)
}
}
}
On both Updated and Created, I don't get the last updated data isUserSignedIn which is True if a user has been logged in though if I put {{isUserSignedIn }} on a template, it shows correctly.
Is there any way to get it to work other than having to use a Watcher here.
Updated: Maybe using Watcher is the only way to get the lastest updated data.