MIxins not working in VueJS - javascript

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()
}
}

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;

Vuex state keeps saying its undefined

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: {
}
}

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

Use vue-router in a mixin

I have my main.js set up like the following:
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource';
Vue.config.productionTip = false;
Vue.use(VueRouter);
Vue.use(VueResource);
Vue.mixin({
methods: {
get_req: function(url) {
Vue.http.get(url, {
before(request) {
// before_callback(request);
}
}).then(response => {
// success_callback(response);
}, response => {
if(response.status == 404) {
Vue.router.push({name: '404'}); // <--- ERROR HERE
}
}).then(response => {
// always_callback(response);
});
}
}
});
const router = new VueRouter({
routes: [
{
path: '/',
component: Home,
meta: {page_title: 'Home'}
},
// ...
]
});
new Vue({
el: '#app',
template: '<App/>',
components: { App },
router: router
});
The error is:
TypeError: Cannot read property 'push' of undefined
So, I know that Vue.router is not defined when I call the mixin method, and I know that a workaround for this is to pass the router itself as argument like something this.get_req(this.$router, 'http://example.com/users/5').
But I trust that there must a better way.
Define your router first, then use it in the mixin.
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueResource from 'vue-resource';
Vue.config.productionTip = false;
Vue.use(VueRouter);
Vue.use(VueResource);
// define the router here
const router = new VueRouter({
routes: [
{
path: '/',
component: Home,
meta: {page_title: 'Home'}
},
// ...
]
});
Vue.mixin({
methods: {
get_req: function(url) {
Vue.http.get(url, {
before(request) {
// before_callback(request);
}
}).then(response => {
// success_callback(response);
}, response => {
if(response.status == 404) {
// Use the router variable you just defined
router.push({name: '404'});
}
}).then(response => {
// always_callback(response);
});
}
}
});
new Vue({
el: '#app',
template: '<App/>',
components: { App },
router: router
});

Categories

Resources