Vuex state keeps saying its undefined - javascript

Here is my post.js under src > store > post.js:
import Vuex from 'vuex'
import Vue from 'vue'
import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
testState: 'Hello',
TV: 0,
},
getters: {
},
mutations: {
},
actions: {
}
})
My index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import post from './post'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
post
}
})
And finally I tried accessing the state in a component.vue:
<template>
<div id="app">
<h3>{{ testState }} {{ TV }}</h3>
</div>
</template>
<script>
import store from './store'
import { mapActions, mapState, mapGetters } from 'vuex'
export default {
name: 'App',
data(){
return {
}
},
computed: {
...mapState(['testState'])
}
}
</script>
However, it keeps giving me an error on the console that says:
Property or method "testState" is not defined on the instance but referenced during render.
When I check in the Vue panel (Chrome's devtools) and I check under Vuex, I can clearly see the testState: 'hello' there so the state exists.
Any tips/advices? Thanks a lot!

You can try this. You can use namespaced modules
// post.js
import axios from 'axios'
export default {
namespaced: true,
state: {
testState: 'Hello',
TV: 0,
},
getters: {
getTestState: state => state.testState
},
mutations: {
setTestState(state, payload) {
state.testState = payload
}
},
actions: {
setTestState({ commit }, payload) {
commit('setTestState', payload)
}
}
}
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
import post from './post'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
post
}
})
// Component
computed: {
...mapState('post', ['testState', 'TV']),
...mapGetters('post', 'getTestState') // this.getTestState
},
methods: {
...mapActions('post', ['setTestState']) // this.setTestState('hello from action')
}

Since you're using a module try out:
...mapState({testState:state=>state.post.testState})
Your module shouldn't create a store instance, it should be like :
export default {
namespaced: true,
state: {
testState: 'Hello',
TV: 0,
},
getters: {
},
mutations: {
},
actions: {
}
}

Related

Migrating Vue 2 to Vue 3, typeError: Vue is not a constructor

How can I migrate my Vue 2 syntax to Vue 3, because I'm receiving the following error:
TypeError: Vue is not a constructor.
Right now I'm using Vue 3:
let app;
firebase.auth().onAuthStateChanged(user => {
console.log("user", user);
if (!app) {
app = new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
}
});
To
import { createApp } from "vue";
const app = createApp({
});
app.mount("#app");
The equivalent of your code in Vue 3, Vuex 4, Vue Router 4 would be something like:
import { createApp } from 'vue'
import store from './store'
import router from './router'
import App from './App.vue'
let app;
firebase.auth().onAuthStateChanged(user => {
console.log("user", user);
app = createApp(App);
app.use(store);
app.use(router);
app.mount("#app");
});
The store syntax is slightly different in store.js:
import { createStore } from 'vuex'
// now uses `createStore`
export default createStore({
state: {},
getters: {},
mutations: {},
actions: {}
})
And the router in router.js:
import { createWebHistory, createRouter } from "vue-router";
import Home from "#/views/Home.vue";
import About from "#/views/About.vue";
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
component: About,
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;

Vue Router - Paths being concatenated multiple times

I am facing problems with the Vue Router and I have no idea what is causing this...
When my application loads it inserts the page path twice.
Example:
If I access the path http://localhost:8080/painel it will be shown in the browser the following path: http://localhost:8080/painel/painel
If I refresh the page the path will be added one more time, going like this: http://localhost:8080/painel/painel/painel
MY files:
/src/main.js
import Vue from 'vue'
import localforage from 'localforage'
import Notifications from 'vue-notification'
import App from './App'
import store from './store'
import router from './router'
import bus from './support/bus'
import http from './support/http'
Vue.config.productionTip = true
window._ = require('lodash')
localforage.config({
driver: localforage.LOCALSTORAGE,
storeName: 'invenio-center'
})
store.dispatch('auth/setToken').then(() => {
store.dispatch('auth/fetchSystemData').catch(() => {
store.dispatch('auth/clearAuth')
})
}).catch(() => {
store.dispatch('auth/clearAuth')
})
Vue.use(Notifications)
Vue.use(bus)
Vue.use(http)
new Vue({
el: '#app',
router,
store,
components: {App},
template: '<App/>'
})
/src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store'
import Login from '../pages/Login'
import Panel from '../pages/Panel'
import PanelIndex from '../pages/panel/Index'
Vue.use(Router)
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'login',
component: Login,
meta: {
visitor: true
}
},
{
path: 'painel',
component: Panel,
meta: {
auth: true
},
children: [
{
path: '/',
name: 'panel.index',
component: PanelIndex
},
{
path: 'idr',
name: 'panel.idr',
component: PanelIndex
}
]
},
{
path: "*",
redirect: {
name: 'panel.index'
},
component: PanelIndex
}
]
})
router.beforeEach(
(to, from, next) => {
store.dispatch('auth/setToken').then(() => {
if(to.meta.visitor){
next({
name: 'panel.index'
});
return;
}
next();
}).catch(() => {
if(to.meta.auth){
next({
name: 'login'
});
return;
}
next();
})
}
)
export default router
/src/pages/Panel.vue
<template>
<div class="panel-container">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Panel',
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.panel-container {
}
</style>
/src/pages/panel/Index.vue
<template>
<div class="index-container">index</div>
</template>
<script>
export default {
name: 'PanelIndex',
data() {
return {
}
}
}
</script>
<style lang="scss" scoped>
.index-container {
}
</style>
try this, add / before path: '/painel', and do that for other components.
/ is used to distinct from relative path.

My global Components are not available

I am new to vuex so i might have only a really dumb mistake.
I am trying to make a reactive Router, for that i used the store from vuex and since i have multiple Components i used a selfwritten Plugin to make them all global. My problem is that the store, where all the routes are saved,and all other components dont have access to the components i set global. I get the following Errormessage:
Uncaught ReferenceError: Home is not defined
my Plugin to make the components global
componentPlugin.js:
import List from "./components/List.vue";
import MainMenu from "./components/MainMenu.vue";
import Test from "./views/Test.vue";
import About from "./views/About.vue";
import Menu from "./views/Menu.vue";
import Home from "./views/Home.vue";
export default {
install(Vue) {
Vue.component("List", List);
Vue.component("MainMenu", MainMenu);
Vue.component("Test", Test);
Vue.component("About", About);
Vue.component("Menu", Menu);
Vue.component("Home", Home);
}
};
my store.js:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
projects: [{ id: 0, title: "Create new Project", compRate: 0 }],
globalid: 1,
projectname: "",
routes: [
{
path: "/home",
name: "home",
component: Home
},
{
path: "/about",
name: "about",
component: About
},
{
path: "/menu",
name: "menu",
component: Menu
}
],
reloaded: 0
},
mutations: {
newProject: (state, project) => {
state.projects.push({
id: project.id,
title: project.title,
compRate: project.compRate
});
},
delProject: (state, id) => {
state.projects.forEach(e => {
if (id === e.id) {
state.projects.splice(state.projects.indexOf(e), 1);
}
});
},
newName: (state, name) => {
state.projectname = name;
},
newRoute: state => {
state.reloaded++;
}
},
actions: {
newProject: ({ commit, state }, project) => {
commit("newProject", {
id: state.globalid,
title: project.title,
compRate: project.compRate
});
state.globalid++;
},
delProject: ({ commit }, id) => {
commit("delProject", id);
},
newRoute: ({ commit }) => {
commit("newRoute");
}
},
getters: {
getProjectNumber(state) {
return state.projects.length;
},
getReloaded(state) {
return state.reloaded;
}
}
});
My main.js:
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
import storePlugin from "./storePlugin";
Vue.use(storePlugin);
import componentPlugin from "./componentPlugin.js";
Vue.use(componentPlugin);
import "./registerServiceWorker.js";
import App from "./App.vue";
import router from "./router.js";
import store from "./store.js";
import BootstrapVue from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
Vue.use(BootstrapVue);
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
The storePlugin is just to make the store global
storePlugin:
import store from "./store";
export default {
store,
install(Vue) {
Vue.prototype.$myStore = store;
}
};
I am using Vue v2.5.17 and vue-router 2.0.
If you need more information, just ask but im pretty sure that this is all that matters.
When you call
import storePlugin from "./storePlugin";
Vue.use(storePlugin);
in main.js your Vue instance doesn't know about the componentPlugin and what it does because it's called after storePlugin (in storePlugin you import the store so there is where I suspect you get the ReferenceError)
Try this:
main.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
import componentPlugin from "./componentPlugin.js";
Vue.use(componentPlugin);
import storePlugin from "./storePlugin";
Vue.use(storePlugin);
import "./registerServiceWorker.js";
import App from "./App.vue";
import router from "./router.js";
import store from "./store.js";
import BootstrapVue from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
Vue.use(BootstrapVue);
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
store.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
projects: [{ id: 0, title: "Create new Project", compRate: 0 }],
globalid: 1,
projectname: "",
routes: [
{
path: "/home",
name: "home",
component: Vue.component('Home')
},
{
path: "/about",
name: "about",
component: Vue.component('About')
},
{
path: "/menu",
name: "menu",
component: Vue.component('Menu')
}
],
reloaded: 0
},
mutations: {
newProject: (state, project) => {
state.projects.push({
id: project.id,
title: project.title,
compRate: project.compRate
});
},
delProject: (state, id) => {
state.projects.forEach(e => {
if (id === e.id) {
state.projects.splice(state.projects.indexOf(e), 1);
}
});
},
newName: (state, name) => {
state.projectname = name;
},
newRoute: state => {
state.reloaded++;
}
},
actions: {
newProject: ({ commit, state }, project) => {
commit("newProject", {
id: state.globalid,
title: project.title,
compRate: project.compRate
});
state.globalid++;
},
delProject: ({ commit }, id) => {
commit("delProject", id);
},
newRoute: ({ commit }) => {
commit("newRoute");
}
},
getters: {
getProjectNumber(state) {
return state.projects.length;
},
getReloaded(state) {
return state.reloaded;
}
}
});
If you want to use the router in vuex I recommend vuex-router-sync

Vue / vue-router scoping

import ExpenseView from './path'
import template from './path'
const MainComponent = new Vue({
el: '#app',
data: {
expense: [{ description: 'expense description', amount: 14.99, _id: 'l;dkfjg;ladfjg;klafjg;l' }],
},
router: new VueRouter({
routes: [
{ path: '/dash', component: ExpenseView, props: { default: true, expenses: MainComponent.expense } },
]
}),
template,
created() {...},
methods: {...},
computed: {...}
})
My goal is to have the router listen to the data in MainComponent but there are scoping issues - MainComponent is not defined.
Is there a way to get the router listening to the data in MainComponent with the way this is structured?
You can see the following example
//you can try the following code
//index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import RSSFeed from '#/components/RSSFeed.vue'
export default new Router({
routes: [
{
path: '/rss-feed',
name: 'RSSFeed',
component: RSSFeed,
props: { authorName: 'Robert' }
},
]
})
//RSSFeed.vue
<template>
<ol id="feed">
{{authorName}}
</ol>
</template>
<script>
import Post from './Post'
export default {
props: ['authorName'],
data () {
return {
items: [
{
"title":"Vuejs Nodejs",
"pubDate":"20-07-2018",
"description":"Leading vuejs nodejs",
"link":"https://hoanguyenit.com"
}
],
errors: []
}
}
}
</script>
Example
//in router
const router = new VueRouter({
routes: [
{ path: 'YOUR__PATH', component: Home, props: { authorName: 'Robert' } }
]
})
//in Home.vue
//And inside the <Home /> component,
var Home = Vue.extend({
props: ['authorName'],
template: '<p>Hey, {{ authorName }}</p>'
});

MIxins not working in VueJS

I have code:
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import VueSession from 'vue-session'
import BootstrapVue from 'bootstrap-vue'
import App from './App'
import router from './router'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import AuthHelper from './utils/AuthHelper'
Vue.config.productionTip = false
Vue.use(BootstrapVue)
Vue.use(VueSession)
Vue.mixin(AuthHelper)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
AuthHelper.js
export default {
methods: {
isLogged () {
if (!this.$session.exists()) {
this.$router.push({
name: 'Login'
})
}
},
logout: () => {
this.$session.destroy()
this.$router.push({
name: 'Login'
})
}
}
}
And my problem is that I can't use method isLogged() in component. Every time I have error that this.isLogged() is not a function.
I am confused, because I do the same as documentation.
#edit
In component I using:
export default {
name: 'Profil',
data () {
return {
user: this.$session.get('user'),
oldpass: '',
newpass: '',
newpassrepeat: '',
error: [],
error2: []
}
},
created () {
this.isLogged()
}
}

Categories

Resources