Vuex $state issue - vue.js

I have error like this:
I previously thought that this is problem with router, but after creating new project with only vuex problem is still there
enter image description here
This is my main.js
import Vue from 'vue'
import App from './App'
import store from './store'
new Vue({
el: "#app",
store,
render: h => h(App)
})
store.js:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
users: [
{id: 1, name: 'Adrian', email: 'adrian#email.pl'},
{id: 2, name: 'Magda', email: 'magda#email.pl'}
]
}
})
and my component using $store:
<template>
<div class="usersNames">
<ul>
<li v-for="user in usersNames">{{user.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'usersNames',
computed: {
usersNames() {
return this.$store.state.users;
}
}
}
</script>

Your examples look like it should work, but I would like to offer a different strategy that I think would be an improvement and should also solve your problem.
Create a getter in your store for the data you're trying to access in your component.
So change your store to this:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state: {
users: [
{id: 1, name: 'Adrian', email: 'adrian#email.pl'},
{id: 2, name: 'Magda', email: 'magda#email.pl'}
]
},
getters:{
users: state => return state.users
}
});
Then, in your component, use that getter to get your users.
<script>
export default {
name: 'usersNames',
computed: {
usersNames() {
return this.$store.getters.users
}
}
}
</script>

you could change main.js:import {store} from './store';

Seems your vuex not inject into vue properly.
Maybe not related to your question, but just for best practice, better use mapState helper;
In your component:
import { mapState } from 'vuex'
export default {
name: 'usersNames',
computed: {
...mapState({
usersNames: 'users'
}),
yourLocalComputed () {}
}
}

Related

Can't access store from Vuex [Quasar]

I'm trying Quasar for the first time and trying to use the Vuex with modules but I can't access the $store property nor with ...mapState. I get the following error 'Cannot read property 'logbook' of undefined' even though I can see that the promise logbook exists on Vue Devtools. Print from Devtools
Here is my store\index.js
import Vue from 'vue';
import Vuex from 'vuex';
import logbook from './logbook';
Vue.use(Vuex);
export default function (/* { ssrContext } */) {
const Store = new Vuex.Store({
modules: {
logbook,
},
strict: process.env.DEV,
});
return Store;
}
Here is the component
<template>
<div>
<div>
<h3>RFID</h3>
<q-btn #click="logData"
label="Save"
class="q-mt-md"
color="teal"
></q-btn>
<q-table
title="Logbook"
:data="data"
:columns="columns"
row-key="uid"
/>
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
name: 'RFID',
mounted() {
this.getLogbookData();
},
methods: {
...mapActions('logbook', ['getLogbookData']),
...mapGetters('logbook', ['loadedLogbook']),
...mapState('logbook', ['logbookData']),
logData: () => {
console.log(this.loadedLogbook);
},
},
data() {
return {
};
},
};
</script>
<style scoped>
</style>
Here is the state.js
export default {
logbookData: [],
};
Error that I get on the console
Update: Solved the problem by refactoring the way I declared the function. I changed from:
logData: () => { console.log(this.loadedLogbook); }
to
logData () { console.log(this.loadedLogbook); }
Check the .quasar/app.js file. Is there a line similar to import createStore from 'app/src/store/index', and the store is later exported with the app in that same file?
I think you confused all the mapx functions.
...mapState and ...mapGetters provide computed properties and should be handled like this
export default {
name: 'RFID',
data() {
return {
};
},
mounted() {
this.getLogbookData();
},
computed: {
...mapGetters('logbook', ['loadedLogbook']),
...mapState('logbook', ['logbookData']),
}
methods: {
...mapActions('logbook', ['getLogbookData']),
logData: () => {
console.log(this.loadedLogbook);
},
}
};

Vuex. Again: Computed properties are not updated after Store changes. The simplest example

I did really read all Google!
Store property "sProp" HAS initial value (=10);
I use Action from component to modify property;
Action COMMITS mutation inside the Store Module;
Mutation uses "Vue.set(..." as advised in many tickets
Component uses mapState, mapGetters, mapActions (!!!)
I also involve Vuex as advised.
I see initial state is 10. But it is not changed after I press button.
However if I console.log Store, I see it is changed. It also is changed in memory only once after the 1st press, but template always shows 10 for both variants. All the other presses do not change value.
Issue: my Computed Property IS NOT REACTIVE!
Consider the simplest example.File names are in comments.
// File: egStoreModule.js
import * as Vue from "vue/dist/vue.js";
const state = {
sProp: 10,
};
const getters = {
gProp: (state) => {
return state.sProp;
}
};
const mutations = {
//generic(state, payload) {},
mProp(state, v) {
Vue.set(state, "sProp", v);
},
};
const actions = {
aProp({commit}, v) {
commit('mProp', v);
return v;
},
};
export default {
namespaced: true
, state
, getters
, mutations
, actions
}
And it's comsumer:
// File: EgStoreModuleComponent.vue
<template>
<!--<div :flag="flag">-->
<div>
<div><h1>{{sProp}} : mapped from Store</h1></div>
<div><h1>{{$store.state.egStoreModule.sProp}} : direct from Store</h1></div>
<button #click="methChangeProp">Change Prop</button>
<button #click="log">log</button>
</div>
</template>
<script>
import {mapActions, mapGetters, mapState} from "vuex";
export default {
name: 'EgStoreModuleComponent',
data() {
return {
flag: true,
};
},
computed: {
...mapState('egStoreModule', ['sProp']),
...mapGetters('egStoreModule', ['gProp'])
},
methods: {
...mapActions('egStoreModule', ['aProp']),
methChangeProp() {
const value = this.sProp + 3;
this.aProp(value);
//this.flag = !this.flag;
},
log() {
console.log("log ++++++++++");
console.log(this.sProp);
},
}
}
</script>
<style scoped>
</style>
Here is how I join the Store Module to Application:
// File: /src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import collection from "./modules/collection";
import egStoreModule from "./modules/egStoreModule";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {},
getters : {},
mutations: {},
actions : {},
modules : {
collection,
egStoreModule
}
});
Finally: main.js
import Vuex from 'vuex'
import {store} from './store'
//...
new Vue({
el: '#app',
router: router,
store,
render: h => h(App),
})
It all works if only I use "flag" field as shown in comments.
It also works if I jump from page and back with Vue-router.
async/await does not help.
I deleted all under node_modules and run npm install.
All Vue/Vuex versions are the latest.

How to access store values to components in vue js

This is my store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
isLoggedIn: !!localStorage.getItem('token'),
isLog : !!localStorage.getItem('situation')
},
mutations: {
loginUser (state) {
state.isLoggedIn = true
state.isLog = true
},
logoutUser (state) {
state.isLoggedIn = false
state.isLog = false
},
}
})
but when I call {{state.isLoggedIn}} in the display.vue, I am not getting the values.
In display.vue, I use
<script>
import axios from "axios";
import store from '../store';
export default {
name: "BookList",
data() {
return {
students: [],
errors: [],
state: this.state.isLoggedIn,
};
},
})
</script>
<template>
{{this.state}}
</template>
But I am getting errors when i done this way. Please can anyone please help what is the problem.
You don't need to import your store into your component. Instead, you should access it using this.$store.
For accessing the store state, the better (and recommended) way is to map the state within your component.
In your example it should be something like:
import { mapState } from 'vuex'
export default {
...
computed: {
...mapState({
isLoggedIn: 'isLoggedIn'
})
}
}
In your template, this is not needed. Just call the property by its name:
{{ isLoggedIn }}

vuejs2: How to pass vuex store to vue-router components

In case when vue-router is not used, store can be passed to child components when declaring new Vue()
But I am using both vue-router and vuex. In this case how can I make store available to components. For e.g. my store.js is typical:
import Vue from 'vue'
import Vuex from 'vuex'
import jwt_decode from 'jwt-decode'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(Vuex);
Vue.use(VueAxios, axios);
export const store = new Vuex.Store({
state: {
jwt: localStorage.getItem('t'),
endpoints: {
obtainJWT: 'http://0.0.0.0:8000/auth/obtain_token',
refreshJWT: 'http://0.0.0.0:8000/auth/refresh_token'
}
},
mutations: {
updateToken(state, newToken){
localStorage.setItem('t', newToken);
state.jwt = newToken;
},
removeToken(state){
localStorage.removeItem('t');
state.jwt = null;
}
},
actions:{
obtainToken(username, password){
//commented code
},
refreshToken(){
//commented code
},
inspectToken(){
//commented code
}
}
});
My main.js file is as below:
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
import { store } from './store'
console.log(store)
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
And router/index.js file is as below:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '#/components/HelloWorld'
import Signup from '#/components/signup/Signup'
import store from '../store.js'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/login',
name: 'Login',
component: function (resolve) {
require(['#/components/login/Login.vue'], resolve)
}
},
{
path: '/signup',
name: 'Signup',
component: Signup
}
]
})
Now how can I pass store to my Signup component. Even though I am passing store in new Vue() it is not available in Signup component
I think the problem is that you importing store and you use the ../store.js,but when you import js file you dont have to use the .js so it has to be import store from '../store'
Also you dont have to pass the vuex store in components using vue-router.
So follow below the installation of vuex store and vue-router!
Vuex Store:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
propertiesName: 'PropValue'
},
getters: {},
mutations: {},
actions: {}
});
Vue-Router:
import Vue from 'vue'
import Router from 'vue-router'
import Page from '#/components/Page.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/Page',
name: 'Page',
component: Page,
},
//other routes
],
mode: 'history',
scrollBehavior(to, from, savedPosition) {
if(savedPosition){ //when use press back button will go at the position he was on the page
return savedPosition
}
if(to.hash){ //if has a hash positition to go
return { selector: to.hash } //go to the page in scrolled Position
}
return { x:0, y: 0 } //go to the page in scroll = 0 Position
}
})
main.js:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { store } from '../store/store'
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
Note:Doing that,now you have access of router and store in all your components
To use the store in your components:
this.$store.state.propertiesName
To use the router in your components:
this.$router.push({name: 'Page'})

Vuex store state is undefined

I am trying to use Vuex ("^2.1.3") with vuejs ("^2.1.10") project in this way:
store.js:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
inTheaters: [
{
name: 'Resident Evil: The Final Chapter',
poster_url: 'https://blackgirlnerds.com/wp-content/uploads/2017/02/Resident-Evil-The-Final-Chapter-Final-Poster-Featured.jpg',
language: 'English',
},
{
name: 'Irada',
poster_url: 'http://filmywave.com/wp-content/uploads/2017/02/irada-movie-poster-1.jpg',
language: 'Hindi',
},
]
},
});
main.js:
import store from './store';
new Vue({
router,
components: {App},
template: '<App/>',
store,
}).$mount('#app');
some-component.js:
<script>
export default {
name: 'movieListWrapper',
props: {
movieListType: {
type: String,
default: 'in-theateras',
},
},
computed: {
movieList() {
return this.$store.state.inTheaters;
}
},
}
</script>
I now have two problems:
First is I get a warning in my console
"export 'default' (imported as 'store') was not found in './store'
The other problem is that the state is not defined.
Uncaught TypeError: Cannot read property 'state' of undefined
I am very new to this and may be I am missing some thing so please pardon me. What am I missing?
In your store.js:
export default new Vuex.Store({ instead of export const store = new Vuex.Store({
Or as #dfsq said import {store} from './store';
//state.js
export const store = new Vuex.Store({
state :{
title :"Welcome in Vuex Tutorials By SK Islam"
}
});
Then in main.js please import the store in this way..
import {store} from "./store/state";
{store}// this is important..