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.
Related
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 am building an authentication page with Vue.js, Vuex, and AWS Amplify.
This auth page is based off Erik Hanchett's AWS Auth Example (https://github.com/ErikCH/Aws-auth-example/blob/master/src/components/HelloWorld.vue). Erik's original demo utilized Vuex for state management, but for the sake of simplicity only employs the state handler in the store.js file.
I am attempting to reconfigure this demo so that the various methods and hooks in HelloWorld.vue are set up to also dispatch actions and commit mutations.
So far, I have been successful in setting up the findUser() method in HelloWorld.vue to dispatch actions, pass user and signedIn as payloads to their respective action handlers, and then commit mutations.
However, my issue now pertains to the computed property in the HelloWorld component.
Erik's original demo returns the state directly to the component using return this.$store.state.signedIn as seen in the computed property. Based on my experience with Vuex in other projects, I would normally use a mapState helper to map directly to the state.
Is it correct in this project to use this.$store.state.signedIn to return the state? Or should I use mapState? If so, how can I reconfigure this computed property in order to employ mapState to map directly to signedIn?
My code is below:
HelloWorld.vue
<template>
<div class="hello">
<div v-if="!signedIn">
<amplify-authenticator></amplify-authenticator>
</div>
<div v-if="signedIn">
<Home></Home>
</div>
</div>
</template>
<script>
import { Auth } from 'aws-amplify'
import { AmplifyEventBus } from 'aws-amplify-vue';
import { mapState } from 'vuex'
import Home from '../components/Home.vue'
export default {
name: 'HelloWorld',
components: {
Home
},
data() {
return {
login: '',
password: ''
}
},
props: {
msg: String,
},
created(){
this.findUser();
AmplifyEventBus.$on('authState', info => {
if(info === "signedIn") {
this.findUser();
} else {
this.$store.state.signedIn = false;
this.$store.state.user = null;
}
});
},
computed: {
signedIn(){
return this.$store.state.signedIn;
}
},
methods: {
async findUser() {
try {
const user = await Auth.currentAuthenticatedUser();
let signedIn = true
this.$store.dispatch('setUser', user)
this.$store.dispatch('setSignedIn', signedIn)
}
catch(err) {
let signedIn = false
this.$store.dispatch('setSignedIn', signedIn)
}
}
}
}
</script>
Store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
user: null,
signedIn: false
},
mutations: {
setUser(state, user) {
state.user = user
},
setSignedIn(state, signedIn) {
state.signedIn = signedIn
}
},
actions: {
setUser: (context, user) => {
context.commit('setUser', user)
},
setSignedIn: (context, signedIn) => {
context.commit('setSignedIn', signedIn)
}
}
})
Home.vue
<template>
<div class="goodbye">
<h1>HOME</h1><br>
<amplify-sign-out></amplify-sign-out>
</div>
</template>
<script>
import { Auth } from 'aws-amplify'
export default {
name: 'Home',
data() {
return {
login: '',
password: ''
}
},
props: {
msg: String,
},
methods: {
signOut() {
Auth.signOut()
}
}
}
</script>
The mapState helper is just sugar syntax for not repeating multiple times the whole this.$store.state.foo piece of code.
You can certainly use mapState like this
import { mapState } from 'vuex'
computed: mapState([
// map this.signedIn to this.$store.state.signedIn
'signedIn'
])
Or like this if you want to also use local properties besides the ones of mapState
import { mapState } from 'vuex'
computed:
localComputed () { /* ... */ },
...mapState([
// map this.signedIn to this.$store.state.signedIn
'signedIn'
])
Here are the docs for more information on this.
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,
I'm trying to split up my Nuxt Vuex store files into separate files. And NOT have all Vuex getters, mutations and actions into one huge file. This demo project is on Github by the way.
I'v read this official Nuxt Vuex Store documentation; but can't seem to get it working. It's a bit vague on where to put stuff.
I have the following in these files:
Below is my: store/index.js
import Vue from "vue";
import Vuex from "vuex";
import Auth from "./modules/auth";
Vue.use(Vuex);
export const store = () => {
return new Vuex.Store({
state: {
},
modules: {
Auth
}
})
}
This is in my: store/auth.js
const state = () => {
username: null
};
const getters = {
username: state => {
return state.username;
},
isAuthenticated: state => {
return state.username != null;
}
};
const mutations = {
login: (vuexContext, username) => {
vuexContext.username = username;
this.$router.push("/dashboard");
},
logout: vuexContext => {
vuexContext.username = null;
this.$router.push("/");
}
};
const actions = {
};
export default {
state,
getters,
mutations,
actions,
};
And finally in my: pages/index.vue
This is where I'm calling that login mutation:
<script>
export default {
layout: "non-logged-in",
data() {
return {
username: null
}
},
methods: {
onSubmit() {
this.$store.commit("login", this.username);
}
}
}
</script>
The error I'm getting:
[vuex] unknown mutation type: login
What am I doing wrong here? I thought i'm importing all the stuff correctly in the store/index.js
You have to export your store constant like this inside your store/index.js file:
export default store
Put this code line at the end of your file.
So as #jeremy.raza described this is what I changed in order to get it working:
store/index.js
import Vue from "vue";
import Vuex from "vuex";
import Auth from "./modules/auth";
Vue.use(Vuex)
const store = () => {
return new Vuex.Store({
state: {
},
modules: {
Auth
}
})
}
export default store;
Changes in the store/auth.js
Note the changes in how I wrote the state, getters and mutations method notation.
const state = () => ({
username: null
});
const getters = {
username(state) {
return state.username;
},
isAuthenticated(state) {
return state.username != null;
}
};
const mutations = {
login(vuexContext, username) {
vuexContext.username = username;
this.$router.push("/dashboard");
},
logout(vuexContext) {
vuexContext.username = null;
this.$router.push("/");
}
};
const actions = {
};
export default {
state,
getters,
mutations,
actions,
};
i just wanna create dynamic registered module in vuex, but it seems doesnt work.
this is my store file
import Vuex from 'vuex'
import descriptionModule from './module/descriptionModule';
const {state: stateModule, getters, mutations} = descriptionModule;
const createStore = () => {
return new Vuex.Store({
state: {
descriptions: [],
},
mutations: {
addDescriptions(state, payload){
state.descriptions.push(state.descriptions.length + 1);
createStore().registerModule(`descriptionModule${payload}`, {
state: stateModule,
getters,
mutations,
namespaced: true // making our module reusable
});
}
}
})
};
export default createStore
and this is my custom module that i will registered
const state = () => {
return {description: ''}
};
const getters = {
description: (state) => state.description
};
const mutations = {
updateDescription(state, payloads){
state.description = payloads;
}
};
export default {
state,getters,mutations
}
and then this is my custom methods that will call addDescriptions mutation and commit updateDescription from registeredModule
beforeMount(){
console.log("hahahaha");
this.$store.commit('addDescriptions', this.id);
},
... more code ....
methods: {
onType(editor, content){
console.log(this.$store.state.a);
console.log(this.$store.state);
console.log(this.$store);
this.$store.commit(`descriptionModule${this.id}/updateDescription`, content, {root: true})
}
}
every onType called, i get an error unknown mutation type: descriptionModuleeditor1/updateDescription in browser.
currently iam following this solution link , but it doesnt work for me :(
can anyone solve this,,, sorry for bad english
invoke $store.registerModule() via component/pages on beforeMount():
beforeMount(){
this.$store.registerModule(`descriptionModule${this.id}`, {
state: stateModule,
getters,
mutations,
namespaced: true // making our module reusable
});
},