Use vue-router in a mixin - javascript

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

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 Routing Guard TypeError

I am trying to guard home page and route user to login page if he/she is not signed in.
To do that I made I made router object so that I can use beforeEach() function.
But I get this error:
This error occurs after I try to make a constant object of router.
router.js is:
import Vue from 'vue';
import Router from 'vue-router';
import firebase from 'firebase';
import Home from './views/Home.vue';
import Signup from './components/auth/Signup.vue';
import Login from './components/auth/Login';
Vue.use(Router);
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home,
meta: {
requiresAuth: true,
},
},
{
path: '/signup',
name: 'Signup',
component: Signup,
},
{
path: '/login',
name: 'Login',
component: Login,
},
],
});
// router guards
router.beforeEach((to, from, next) => {
// check to see if routh require auth
if (to.matched.some(rec => rec.meta.requiresAuth)) {
// check state of user
const user = firebase.auth().currentUser;
if (user) {
next();
} else {
next({ name: 'Login' });
}
} else {
next();
}
});
This is is in main.js file.
import Vue from 'vue';
import firebase from 'firebase';
import router from './router';
import App from './App.vue';
Vue.config.productionTip = false;
const app = null;
// Wait for firebase init the user
firebase.auth().onAuthStateChanged(() => {
// init the app if not created
if (!app) {
new Vue({
router,
render: h => h(App),
}).$mount('#app');
}
});
Add the below changes
Add this line to last in router.js
export default router;
Add In main.js
import router from './router'; (path should point to your router.js)
new Vue({
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.

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

vue.js variable in Vuex store not accessible in component

I have defined BASE_URL in Vuex store/store.js
export const store = new Vuex.Store({
state: {
BASE_URL: 'http://127.0.0.1:8090',
isAuthenticated: false
},
...
and imported the store to main.js
import Vue from 'vue'
import App from './App.vue'
import VueResource from 'vue-resource'
import VueRouter from 'vue-router'
import Routes from './routes'
import {store} from './store/store'
Vue.use(VueResource)
Vue.use(VueRouter);
const router = new VueRouter({
routes: Routes,
mode: 'history'
});
new Vue({
store: store,
el: '#app',
router: router,
render: h => h(App)
});
However, when I try to import BASE_URL in a component:
computed: {
BASE_URL () {
return this.$store.state.BASE_URL;
}
},
methods: {
login: function () {
axios.post( BASE_URL + "/api/login", {
username: this.username,
password: this.password,
}).then(function(data){
console.log(data);
});
},
I get this error:
Uncaught ReferenceError: BASE_URL is not defined
at VueComponent.login (webLogin.vue?e2e5:175)
at Proxy.boundFn (...
What could be wrong here? How to fix it?
You have typo in code in method login:
login: function () {
axios.post( this.BASE_URL + "/api/login", { // you must have this here
username: this.username,
password: this.password,
}).then(function(data){
console.log(data);
});
},

Categories

Resources