I'm experimenting with vuex and I was looking for best way to organize my vuex files I finished with something like this:
/src/store/user/state.js:
export default {
state: {
user: null
}
}
/src/store/user/getters.js:
export default {
getters: {
user (state) {
return state.user
}
}
}
/src/store/user/mutations.js:
export default {
mutations: {
'SET_USER' (state, user) {
state.user = user
}
}
}
/src/store/user/actions.js
export default {
actions: {
loginUser ({ commit }, params) {
commit('SET_USER', {id: 1})
}
}
}
/src/store/user/index.js
import state from './state'
import getters from './getters'
import actions from './actions'
import mutations from './mutations'
export default {
state,
getters,
actions,
mutations
}
/src/store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user
}
})
When I load my code it returns in console following error:
vuex: unknown getter: user
Each of your user-related files are using export default, which means when you import those files, you are naming the entire object being exported state, getters, etc.
So, in the scope of index, the state variable has a property named state, the getters variable has a property named getters, etc. And this is throwing things off.
You should export a const for each of these files instead:
export const state = {
user: null,
}
And then when importing grab the named const like so:
import { state } from './state'
Alternatively, you could just remove the properties for state, getters, etc. from each file:
// state.js
export default {
user: null,
}
And then import like you're doing already:
import state from './state'
Related
I have setup a default store in Nuxt in store/index.js as the documentation recommends. When I try to render my app I'm getting the following error:
Uncaught Error: [nuxt] store/index.js should export a method that
returns a Vuex instance.
My store/index.js file looks like this:
import Vuex from 'vuex'
import Vue from 'vue'
import myModule from './myModule'
Vue.use(Vuex)
const store = new Vuex.Store({
state: () => ({
}),
mutations: {},
actions: {},
modules: {
myModule: myModule
}
})
export default store
How do I handle this?
You are exporting the Vuex store as a constant, you should export a default method that returns the Vuex store instance.
Your store/index.js file should look like this:
import Vuex from 'vuex'
import Vue from 'vue'
import myModule from './myModule'
Vue.use(Vuex)
export default () => new Vuex.Store({
state: () => ({
}),
mutations: {},
actions: {},
modules: {
myModule: myModule
}
})
I do have the following and it's working great.
import { test } from './modules/tasty_module'
const state = () => ({})
const mutations = {}
const actions = {}
const getters = {}
export default {
state,
mutations,
getters,
actions,
modules: {
testModule: test,
},
}
I have this Read.js that reads an image. And I want to save the content of the image (in bytes) into a vuex Store.
I'm trying to import the store into Read.js with:
import Store from "src/store/index";
After I read the bytes, I try to access the actions to save it to the state using:
Store.actions.A_updateImage(payload);
But i get that ".actions" is "Undefined".
This is the main store file that import the modules:
//src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import My_store from './modules/My_store'
Vue.use(Vuex)
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
My_store
},
strict: process.env.DEBUGGING
})
return Store
}
This is the store module that has the action i want to use:
//src/store/modules/My_store.js
const state = {
Image: {}
}
const mutations = {
M_updateImage: (state, Image) => {
state.Image = Image;
},
}
const actions = {
A_updateImage({ commit }, Image) {
commit('M_updateImage', Image)
}
}
const getters = {
getImage:(state) =>{
return state.image
}
}
export default {
namespaced: true,
getters,
mutations,
actions,
state
}
How can I import and call the action I need to use from the Read.js file?
Thank you
I am importing a Vuex module. Everything works fine if I don't namespace it, but when I do namespace it is reports that the action is "not a function." when called.
index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import MainWindow from './modules/MainWindow';
import ArtEditor from './modules/ArtEditor';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
MainWindow,
ArtEditor
}
});
ArtEditor module:
const state = {
selectedColor : "#FFFFFF"
}
const getters = {
selectedColor: state => state.selectedColor
};
const actions = {
selectColor({commit}, newColor){
commit('selectColor', newColor);
console.log(newColor)
}
};
const mutations = {
selectColor: (state, newColor) => state.selectedColor = newColor
};
export default {
namespaced: true,
state,
getters,
actions,
mutations
};
in Vue component:
import {mapActions, mapGetters} from 'vuex';
...
methods:{
...mapActions(['ArtEditor/selectColor']),
colorChanged(color){
this.selectColor(color);
}
},
...
when the color is changed, it throws the error this.selectColor is not a function. Most of the documentation on namespaced modules either doesn't import external Vuex modules, or uses dispatch() instead of mapActions(), I really don't know what I'm doing wrong.
Your syntax is off, you need to either do:
...mapActions(['ArtEditor/selectColor']),
colorChanged(color){
this['ArtEditor/selectColor'](color);
}
Or separate the action path while mapping:
...mapActions('ArtEditor', ['selectColor']),
colorChanged(color){
this.selectColor(color);
}
See binding helpers with namespace.
I wrote the following code but it shows an error. What is the reason for this?
Error
[vuex] unknown action type: showRegisterLogin/show
HomePage.vue // component
When using the sh method This error is caused
import { mapState, mapActions } from "vuex";
export default {
name: "HomePage",
components: {
RegisterLogin
},
data() {
return {}
},
computed: {
...mapState({
showRegisterLogin: state => state.showRegisterLogin.show
}),
},
methods: {
sh() {
this.$store.dispatch('showRegisterLogin/show');
}
}
}
/ store / modules / showRegisterLogin.js
// States
const state = {
show: false,
};
// Getters
const getter = {
show (state) {
return state.show;
}
};
// Mutations
const mutation = {
showPage (state) {
return state.show = true;
},
hidePage (state) {
return state.show = false;
}
};
// Actions
const action = {
show({ commit }) {
commit('showPage');
},
hide({ commit }) {
commit('hidePage');
}
};
export default {
namespaced: true,
state,
getter,
mutation,
action
}
/ store / store.js
'use strict';
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import showRegisterLogin from "./modules/showRegisterLogin";
export default new Vuex.Store({
modules: {
showRegisterLogin,
}
});
I also imported the store.js file into app.js and registered it in new vue
The structure of the store, module, and component are fine, except for the name of the store objects in your module:
getter should be getters
mutation should be mutations
action should be actions
Probably just typos. Those can't be arbitrarily named since Vuex looks specifically for those keys.
I have this store.js file
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const mutations = {
increment: state => state.count++,
Changeloading(state, status) { state.loading = status },
ChangeUserGroup(state, newGroup) { state.userGroup = newGroup; },
ChangeOriginalRole(state, newRole) { state.originalRole = newRole; }
}
export default new Vuex.Store({
state: {
count: 0,
loading: false, //header, TeamLead, TeamMember
listUserGroup: [],
userRole: "",
originalRole: "",
userGroup: {}
},
mutations,
...
})
In my testing file store.spec.js
import { expect } from 'chai'
import mutations from '#/store'
// destructure assign `mutations`
const { increment } = mutations
describe('mutations', () => {
it('INCREMENT', () => {
// mock state
const state = { count: 0 }
// apply mutation
increment(state)
// assert result
expect(state.count).to.equal(1)
})
})
This is the result i am getting:
mutations
1) INCREMENT
0 passing (75ms)
1 failing
1) mutations
INCREMENT:
TypeError: increment is not a function
at Context.increment (dist\webpack:\tests\unit\store.spec.js:13:5)
EDIT (4/16/2019)
I walk down one more step. I saw here that I should "export" all the components in my store.js like:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const mutations = {...};
export const state = {...};
export const actions = {...};
export const getters = {...};
export default new Vuex.Store({
state,
mutations,
actions,
getters
});
But even in that way... I'm getting the ugly (testing fail message)
0 passing (61ms)
1 failing
1) mutations
increment:
TypeError: increment is not a function
at Context.increment (dist\webpack:\tests\unit\store.spec.js:12:5)
I finally found the answer for this one:
In my test file I have
import { expect } from 'chai'
import mutations from '#/store'
right way to import mutations should be...
import { expect } from 'chai'
import {mutations} from '#/store'
The case was resolved :) by { }
Regards,