Vuex store initiated in mainjs but is undefined in App.vue - vue.js

main.js:
import Vue from "vue";
import Axios from "axios";
import App from "./App.vue";
import router from "./router";
import store from "./store";
const axios = Axios.create({
baseURL: process.env.VUE_APP_BASE_URL
})
Vue.prototype.$http = axios;
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
when I try to use $store in App.vue it is undefined:
created() {
this.$store.dispatch('logout') // this.$store is undefined
}
store.js:
export default new Vuex.Store({
actions: {
logout({commit}) {
return new Promise((resolve, reject) => {
commit('logout')
localStorage.removeItem('token')
delete Vue.prototype.$http.defaults.headers.common['Authorization']
resolve()
})
}
}
}
Is it because it is not initiated in App.vue, because I can use at other vue components.

You haven't imported Vuex in Main.JS:
import Vuex from 'vuex'
Vue.use(Vuex)
Learn more about installing Vuex here
EDIT: Legit everyone just stole my answer...

import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
// Options
});
And just put to the Vue Instance.
Hope it helps you.

First, you need to install Vuex using npm install vuex --save
Then, import it into your store.js.
To understand WHEN, WHY and HOW to use Vuex, refer this URL https://dev.to/napoleon039/when-why-and-how-to-use-vuex-9fl

Related

commit api data to vuex from component

I am trying to push data from an api call to my store, but I keep getting errors like commit is undefined and dispatch is undefined.
If I understood documents correctly I can only manipulate state from components by creating mutations? been going round in circles for an hour now and would appreciate some guidance.
in main.js
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
import 'es6-promise/auto'
Vue.config.productionTip = false
new Vue({
router,
render: (h) => h(App),
store: store,
}).$mount('#app')
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
images: [],
},
mutations: {
addImages(state, newImages) {
state.images = []
state.images.push(newImages)
},
},
})
Header.js component:
<template>
<div>
<h1>Nasa Image Search</h1>
<div class="search-container">
<form action="/action_page.php">
<input v-model="searchWord" type="text" placeholder="Search.." name="search" />
<button v-on:click.prevent="search" type="submit">Search</button>
</form>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Header',
data: () => ({
searchWord: "",
//images: [],
}),
methods: {
search() {
let url
this.searchWord
? url = `https://images-api.nasa.gov/search?q=${this.searchWord}&media_type=image`
: url = `https://images-api.nasa.gov/search?q=latest&media_type=image`
console.log(url) //bug testing
axios
.get(url)
.then(response => {
const items = response.data.collection.items
console.log(items)
this.$store.commit('addImages', items)
console.log(this.$store.state.images)
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
Your code is perfectly fine, please create a new file store.js as below and import it in main.js and it will work. In newer version of vuex eg 4.0 we do have createStore function using which we can include store code in main.js file itself.
store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: { images: [], },
mutations: {
addImages(state, newImages) {
state.images = []
state.images.push(newImages)
},
},
});
main.js
import Vue from "vue";
import App from "./App.vue";
import { store } from "./store";
import router from './router'
import 'es6-promise/auto'
Vue.config.productionTip = false;
new Vue({
router, store,
render: h => h(App)
}).$mount("#app");
in Vue 3 with Vuex 4 -> We can have store code inside main.js as below. doc link https://next.vuex.vuejs.org/guide/#the-simplest-store
import { createStore } from 'vuex'
import { createApp } from 'vue'
const store = createStore({
state () {
return {
}
}
})
const app = createApp({ /* your root component */ })
app.use(store)
Normally I create my Vuex 'store' in a separate file and import it into main.js.
I did a local experiment where I declared 'const store' in main.js AFTER instantiating new Vue() in main.js, as you are doing, and am getting errors.
Try declaring 'const store' BEFORE new Vue().

Vuex this.$store is undefined

I'm trying learning vue with vux and vuetify. I've installed it via vue cli.
Like in the documentation, I try to get access of the store, but got an undefined for this.$storage.
src/components/HelloWorld.vue
<script>
export default {
methods: {
onChangeTheme: () => {
console.log(this.$store)
}
}
};
</script>
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify';
Vue.config.productionTip = false
new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app')
src/store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
Don’t use arrow functions on an options property or callback, such as created: () => console.log(this.a) or vm.$watch('a', newValue => this.myMethod()). Since an arrow function doesn’t have a this, this will be treated as any other variable and lexically looked up through parent scopes until found, often resulting in errors such as Uncaught TypeError: Cannot read property of undefined or Uncaught TypeError: this.myMethod is not a function.
This is explained here.

How can I fix '[vuex] unknown action type: lookupName' within my Vue component?

I am having an issue calling up an action from my Vue component using this.$store.dispatch('lookupName'). I have tried console logging the this.$store method, but the actions within it are empty.
Main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { findCertificate } from '#/api';
Vue.use(Vuex)
const state = {
// single source of data
nameLookup: {},
}
const actions = {
// asynchronous operations
lookupName(context, form){
return findCertificate(form)
}
}
const store = new Vuex.Store({
state,
actions,
mutations,
getters
})
export default store
Vue Component
import VueRecaptcha from 'vue-recaptcha';
import { mapGetters, mapActions} from 'vuex'
export default {
created() {
},
methods: {
...mapActions({
lookupName: 'lookupName'
}),
...mapActions({
add: 'lookupName'
}),
onCaptchaVerified: function(recaptchaToken){
this.$refs.recaptcha.reset();
console.log(this.$store.dispatch('lookupName', this.form))
},
}
}
Why am I still getting this error? I have looked up many other people's questions about similar issues, but those solutions did not work for me.

Vuex doesn't work as expected - problem with import?

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 vue-cli vuex , use this.$store can't get store object, but use this.$store.store it works

that this.$store.state I get a undefined, but use this.$store.store get a correct result
store/index.js
It's caused by that export default. Try to export directly the const.
Example:
store.js
import 'Vue' from 'vue';
import 'Vuex' from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
//your code here//
}
});
Main.js
import 'store' from 'wherever the file is/mystore.js';
new Vue({
el: '#app',
store, <-- Here is defined store to use along the my app
render: h => h(App)
});