I have a very simple VueJS example I'm having some trouble with.
I have a js file called enums.js with the following line in it
export const modeEnumeration = { PLAYBACK: 'playback', RECORDING: 'recording', NONE: 'none' };
I'd like to set the initial value of a property in Vuex state to one of these modeEnumeration values. So this is my Vuex store.
import Vue from 'vue';
import Vuex from 'vuex';
import modeEnumeration from '../constants/enums';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
mode: modeEnumeration.NONE,
},
mutations: {
},
actions: {
},
modules: {
},
getters: {
},
});
However, I keep getting the following error in my Vuex store...
Uncaught TypeError: Cannot read property 'NONE' of undefined
What am I missing?
You export a named object, so you need to import it with curly braces:
import { modeEnumeration } from '../constants/enums';
The other solution would be to export a default:
export default { PLAYBACK: 'playback', RECORDING: 'recording', NONE: 'none' };
Related
I have an issue with mutations in Vuex - In my component I have passed the getters and mutations, so that I can used the data. However, the getters are getting passed down just fine and can be retrieved from the component, but regarding the mutations, they all seem to be getting undefined. I have another component with identical setup, which seems to work fine.
Here is the code related to the component I have an issue with:
https://codesandbox.io/s/nlpvz0y6m
So far, I have tried retrieving the data by importing the whole store
but it isn't what I must do and not optimal.
Please advise further.
store:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
stats: {
controls: {
spin: false
}
},
getters: {
isSpinning: state => {
return state.controls.spin;
}
},
mutations: {
spinIt(state) {
return (state.controls.spin = !state.controls.spin);
}
}
}
});
component:
<template>
<div>
<div class="spin">
<span #click="spinIt">SPIN</span>
</div>
</div>
</template>
<script>
import {mapMutations} from 'vuex';
import {mapGetters} from 'vuex';
export default {
name: 'Stake',
computed: {
...mapMutations(['spinIt']),
...mapGetters(['isSpinning'])
}
}
</script>
First you need restructure the Vuex instance by the following:
export const store = new Vuex.Store({
state: {
stats: {
controls: {
spin: false
}
},
},
getters: {
isSpinning: state => {
return state.stats.controls.spin;
}
},
mutations: {
spinIt(state) {
return (state.stats.controls.spin = !state.stats.controls.spin);
}
}
});
Now you will access the getters and mutations.
After that, move the mapMutations into the methods block in your Spin.vue:
<script>
import {mapMutations} from 'vuex';
import {mapGetters} from 'vuex';
export default {
name: 'Stake',
computed: {
...mapGetters(['isSpinning'])
},
methods: {
...mapMutations(['spinIt'])
}
}
</script>
I created my store store/user.js
export const state = () => ({
user: {},
});
export const mutations = {
};
export const actions = {
AUTH ({commit},{email, password}){
console.log('email, password =', email, password)
}
};
export const getters = {};
component:
<template>
<form #submit.prevent="AUTH(model)">
<input type="text" required v-model.lazy = "model.email">
<input type="password" required v-model.lazy = "model.password" >
</template>
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {
model:{
email:" " ,
password:" "
}
}
},
methods: {
...mapActions(['AUTH']),
}
}
In my component , I am trying to execute a vuex action from a module, but I am getting an error, even if this action is defined :
unknown action type: AUTH,
I don't have any idey about problem.
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user.js'
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
user
}
})
You need to use createNamespacedHelpers:
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('users')
Binding helpers with namespace
Otherwise, the mapping helpers need the full module namespace:
...mapActions([
'users/AUTH'
])
// if you are only using one module in the component
...mapActions('users', [
'AUTH'
])
Nuxt
You're mixing classic and modules mode. When using modules mode, Nuxt creates the store instance from the index.js file. You simply export the state, getters, mutations and actions. State should be exported as a function:
export const state = () => ({
foo: 0,
bar: 1
})
Any file within the store directory will be considered a module and Nuxt will automatically register it as a namespaced module.
- store
-- index.js // the store
-- users.js // module 'users'
-- foo.js // module 'foo'
The users module looks otherwise correct.
Make the following changes to your component:
// template
<form #submit.prevent="submitForm">
// script
methods: {
...mapActions({
auth: 'users/AUTH'
}),
submitForm () {
this.auth(this.model)
}
}
I'm trying to create a vue plugin but I'm getting the error:
[Vue warn]: Property or method "count" is not defined on the instance but
referenced during render. Make sure to declare reactive data properties in the
data option.
I would like to create a single file component which I can import and use but I keep getting this error once I add {{count}} to the template.
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import Vuex from 'vuex'
import Counter from '/components/counter'
Vue.config.productionTip = false
Vue.use(Counter)
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
let app = new Vue({
el: '#app',
router,
template: '<App/>',
store:store,
components: { App, Counter }
})
counter/index.js
import Counter from './Counter'
const install = function(Vue, opts){
Vue.component('counter',Counter)
}
export default { install }
counter/counter.vue
<template lang="pug">
div {{ count }}
</template>
export default {
data(){
return {
count : 0
}
},
computed: {
count () {
return this.$store.state.count
}
}
}
Update : I added the tag, but my $store is not defined and I'm getting the error:
vue.esm.js?0de7:476 [Vue warn]: Error in render function: "TypeError: Cannot read property 'state' of undefined"
How can I access the vuex Store from this component? From the vuex doc:
By providing the store option to the root instance, the store will be
injected into all child components of the root and will be available on them
as this.$store.
I've got a little Vuex store (like below) and I use vuex-router-sync to keep it in sync. This adds a router module to my store, but how would I get this object out of the store as there don't seem to be any associated getters with this module?
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import module1 from './modules/module1'
import module2 from './modules/module2'
import module3 from './modules/module3'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
module1,
module2,
module3
}
})
main.js
import App from './views/App/App'
import store from './store'
import router from './router'
import { sync } from 'vuex-router-sync'
// sync router with store
sync(store, router)
new Vue({
el: '#app',
store,
router,
render: h => h(App)
})
My state would look something like this:
{
module1: {
cheese: true
},
module2: {
crackers: true
},
module3: {
wine: true
},
route: {
from: {}
fullPath:"/path/to/cheese"
hash:""
meta: {}
name:"cheese"
params: {}
path:"/path/to/cheese"
query: {}
}
}
Basically what I'm trying to do is add a title in my app header that updates depending on what page/view you are on.
Header.vue
export default {
name: 'header',
computed: {
getRouteTitle () => {
return this.$store.getters.getRouteTitle
}
}
}
Header.html
<header>
<h1>{{ getRouteTitle }}</h1>
</header>
Found a solution that works quite well. vuex-router-sync fires an action to telling us that the route has changed. Within one of our existing modules you can listen out of this and make a subsequent mutation. For me this would be setting the title from the router/ROUTE_CHANGED action payload.
router.js
const router = [
{
name: 'Cheese',
path: 'cheese',
component: Cheese,
meta: { title: 'Calendar', requiresAuth: true }
},
]
module1.js
import * as types from '../mutation-types'
// Initial State
const state = {
cheese: true,
title: 'App'
}
// Getters
export const getters = {
getRouteTitle: state => state.title
}
// Mutations
export const mutations = {
'router/ROUTE_CHANGED' (state, payload) {
state.title = payload.to.meta.title
}
}
export default {
getters,
mutations,
state
}
Hope that makes sense and please let me know if there is a better solution :)
******* UPDATE *********
A super easy way is just to get the $router instance in your component like this:
<h1>{{$route.name}}</h1>
Which would render to:
<h1>Cheese</h1>
I am struggling to developed a project with vuejs and vuex, but it does not work with this.$store.state.count in the component. Why?
My config:
"vuex": "^2.0.0"
store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 12
},
mutations: {
increment (state) {
state.count++
}
},
strict: true
})
main.js:
import store from './vuex/store'
import Vue from 'vue'
new Vue({
store,
.
.
.
}).$mount('#app')
component.js:
<script>
export default {
name: 'landing-page',
created: () => {
console.log('status2')
console.log(this.$store.state.count)
}
}
</script>
Error:
Uncaught TypeError: Cannot read property '$store' of undefined
You will never, ever edit the store directly.
You will ALWAYS trigger mutations.
As so (component.js):
<script>
import store from './vuex/store'
export default {
name: 'landing-page',
computed: {
counter () {
return store.state.count // get state
}
},
created: () => {
store.commit('increment') // set state
}
}
</script>
That is because this in arrow function is not what you expect as this in "normal function". You can refer to Arrow functions or Javascript ES6 — Arrow Functions and Lexical this for more information