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..
Related
I work with microfrontend single-spa (https://single-spa.js.org/)
I create a store
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
}
})
in src/main.js i import it
import Vue from 'vue';
import singleSpaVue from 'single-spa-vue';
import 'devextreme/dist/css/dx.light.css';
import App from './App.vue';
import store from './store';
console.log("π ~ file: main.js ~ line 6 ~ store", store)
Vue.config.productionTip = false;
Vue.prototype.$bus = new Vue();
const vueLifecycles = singleSpaVue({
store,
Vue,
appOptions: {
render(h) {
return h(App, {
store,
props: {
},
});
},
},
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
in console.log store displayed, but in the app cnsole.log(this) does not contain store
I don't understand where I am connecting wrong?
According to the docs, store should be a subproperty of appOptions:
const vueLifecycles = singleSpaVue({
// store, β
Vue,
appOptions: {
store, β
render(h) {
return h(App, {
// store, β
props: {},
})
},
},
})
Uncaught ReferenceError: photoModule is not defined
Πhe first time I encountered such an error so that the vuex store does not find the module.
What could be the problem?
vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
photoModule
}
})
main.js
import store from './store'
Vue.prototype.axios = axios
Vue.config.productionTip = false
new Vue({
vuetify,
router,
store,
render: h => h(App)
}).$mount('#app')
photoModule
import axios from 'axios'
export default {
state: {
photos: []
},
mitations: {
setPhotos(state, payload) {
state.photos = payload
}
},
getters: {
getAllPhotos(state) {
return state.photos
}
},
actions: {
fetchPhotos(context) {
axios.get('https://jsonplaceholder.typicode.com/photos?_limit=10')
.then(response => this.photos = context.commit('setPhotos', response.data))
}
}
}
For the second day I have been sitting on this error. At least hint where something is wrong
You didn't import the module
import Vue from 'vue'
import Vuex from 'vuex'
import photoModule from './photoModule.js' // β
Add this
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
photoModule
}
})
Trying to use Vuex states in components.
This works fine:
main.js:
const store = new Vuex.Store({
state: {
counter: 1
},
mutations: {
increment(state) {
state.counter++
}
}
})
new Vue({
store,
render: h => h(App)
}).$mount('#app')
and inside component:
<span>{{this.$store.state.test}}</span>
When I tried to move Vuex to a separate store.js, it doesn't work.
store.js (right near main.js):
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter: 1
},
mutations: {
increment(state) {
state.counter++
}
}
})
and inside component I make import:
import store from '../store',
than try to use:
<span>{{store.state.test}}</span>
and I get
Property or method "store" is not defined on the instance
<span>{{this.$store.state.test}}</span> results
Uncaught ReferenceError: store is not defined
I've tried to change export default new Vuex.Store({...}) to export const store = new Vuex.Store({...}) but it didn't helped.
P. S. This works for me:
inside component:
computed: {
counter() {
return store.state.counter
}
}
and <span>{{counter}}</span>.
But is there other way without using computed properties? Because I use Vuex for calling its states globally, and here I have to define computed in each component anywhere...
your export and import don't follow the ES6 rules,
if you are using export const store = new Vuex.Store({...})
you need to either import like this
import {store} from '../store.js'
if not, update your code to this:
import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex)
export default const store = new Vuex.Store({ state: {
counter: 1 }, mutations: {
increment(state) {
state.counter++
} } })
I went this way:
store.js:
export default new Vuex.Store({...})
main.js:
import store from './store'
new Vue({
...
store,
render: h => h(App)
}).$mount('#app')
Than in any component's template: <span>{{this.$store.state.counter}}</span>.
Can't confirm this is the best way, but it works for me.
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'})
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 () {}
}
}