Why is $store not defined? - javascript

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

Related

globally accessing const variables from a Vuex store

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' };

ReferenceError state is not defined in vuex store

My vuex store looks like this but when calling addCustomer I get ReferenceError: state is not defined:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: { customers: [] },
mutations: {
addCustomer: function (customer) {
state.customers.push(customer); // error is thrown here
}
}
});
This is the addCustomer binding/template:
<template>
<button class="button" #click="addCustomer">Add Customer</button>
</template>
This is the definition for addCustomer:
<script>
export default {
name: "bootstrap",
methods: {
addCustomer: function() {
const customer = {
name: 'Some Name',
};
this.$store.commit('addCustomer', customer);
}
}
}
</script>
You're missing the state in addCustomer function parameters (addCustomer: function (customer)) :
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: { customers: [] },
mutations: {
addCustomer: function (state,customer) {
state.customers.push(customer); // error is thrown here
}
}
});

Mutations undefined Vuex

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>

Uncaught TypeError: this.$store.commit is not a function

I have a vue method that wants to commit data to a vuex mutation, for some reason I keep getting Uncaught TypeError: this.$store.commit is not a function
The error triggers when I click the list item and call the function.
sample.vue
<li class="tabs-title" v-for="item in filteredItems" v-on:click="upComponents" :key="item.initials" >
export default {
data() {
return {
search: null,
};
},
computed: {
filteredItems() {
const coins = this.$store.state.coin.coin;
if (!this.search) return coins;
const searchValue = this.search.toLowerCase();
const filter = coin => coin.initials.toLowerCase().includes(searchValue) ||
coin.name.toLowerCase().includes(searchValue);
return coins.filter(filter);
},
},
methods: {
upComponents(item) {
this.$store.commit('updatedComp', item);
},
},
mounted() {
this.tabs = new Foundation.Tabs($('#exchange-tabs'), {
matchHeight: false,
});
},
destroyed() {
this.tabs.destroy();
},
};
This is the store.js file where I declare the mutation.
import Vue from 'vue';
import Vuex from 'vuex';
import coin from '../data/system.json';
Vue.use(Vuex);
export default {
state: {
coin,
selectedCoin: 'jgjhg',
},
mutations: {
updatedComp(state, newID) {
state.selectedCoin.push(newID);
},
},
getters: {
coin: state => state.coin,
},
};
main.js, this is where I declare the Vue app
import jQuery from 'jquery';
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store/store';
window.jQuery = jQuery;
window.$ = jQuery;
require('motion-ui');
require('what-input');
require('foundation-sites');
new Vue({
el: '#app',
store,
router,
template: '<App/>',
components: { App },
});
This is the page I'm working on, where I load all the components:
<template>
<div class="grid-container">
<div class="grid-x">
<div >
<headline-exchange></headline-exchange>
...
</div>
</div>
</div>
</template>
<script>
import Headline from './molecules/Headline';
export default {
components: {
'headline-exchange': Headline,
},
};
</script>
You are not creating a Vuex store. All you have is an object defining the store properties.
Change your store.js to be
export default new Vuex.Store({
state: { ... },
mutations: { ... },
// etc
})
See https://vuex.vuejs.org/guide/#the-simplest-store

How to get a key from route module using vuex-router-sync

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>

Categories