How to use router push inside a VueJs component? - javascript

I have a navbar component, I need to redirect to the login component inside a logout method declared at navbar.
I tried: this.$router.push({name:'MyLogin'});
But I see the error:
vue-router.esm.js?8c4f:1897 TypeError: Cannot read property '$router' of undefined
at eval (main.js?56d7:68)
How can I use router push inside a component?
Or how can I inside this component make access to the router.
EDIT :
At the file: /src/router.js I have the Login route:
export default new Router({
mode: 'history',
routes: [
{
path: '/login',
name: 'Login',
component: LoginView
},
And at the file: /src/components/Navibar.vue I have the doLogout method:
methods: {
doLogout(){
this.$router.push({name:'Login'});
}
Being new to Vue js I tried this:
doLogout(){
const router = new router({
routes: [
{
path: '/login',
name: 'Login',
component: LoginView
}
]
})
this.$router.push({name:'Login'});
}
I see the error message:
doLogout catch ReferenceError: LoginView is not defined at eval (VM2993 NaviBar.vue:324)
So I tried to add the component:
Vue.component('LoginView', require('Login.vue'));
Which gives me the error:
Module not found: Error: Can't resolve 'Login.vue'
Maybe I am doing the wrong steps?
Which is the correct way to enable this.$router.push() inside one component redirecting to another component?

Try declaring as below :
At the file: /src/router.js
const router = new Router({
mode: 'history',
routes: [
{
path: '/login',
name: 'Login',
component: LoginView
},
export default router
The router variable declared is accessible over all vue components.
Hence at the file: /src/components/Navibar.vue doLogout method :
methods: {
doLogout(){
this.$router.push({name:'Login'});
}

Related

How to add a new file with routes in vue?

I have a main router.js file where I want to use the another file with routes - routeManagement.
router.js:
import routesManagement from './routesManagement'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Dashboard',
component: Dashboard
},
routesManagement,
]
export default router
routesManagement.js:
import Tools from '../../views/management/Tools.vue'
const routeManagement = [
{
path: '/tools',
name: 'Tools',
component: Tools
},
]
export default routeManagement
When I do this, the app stops working and I get an error:
Uncaught Error: [vue-router] "path" is required in a route configuration.
How to fix it? What am I doing wrong?
Destructure the routesManagement array:
const routes = [
{
path: '/',
name: 'Dashboard',
component: Dashboard
},
...routesManagement,
]

How to use vue-gapi plugin with router.js and router guards [duplicate]

This question already has an answer here:
Is there a way to accees vue js VueSession in main.js
(1 answer)
Closed 1 year ago.
I use a vue-gapi https://www.npmjs.com/package/vue-gapi in my code to access Google Calendar API. I was successful to install and use this plugin to get data from Calendar API. I now struggle to use router guards.
plugins/vuagapi.js:
import Vue from 'vue';
import VueGapi from 'vue-gapi';
const apiConfig = {
apiKey: '***',
clientId:
'***.apps.googleusercontent.com',
discoveryDocs: [
'https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest',
],
scope: 'https://www.googleapis.com/auth/calendar.readonly',
prompt: 'select_account',
};
Vue.use(VueGapi, apiConfig);
router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import Dashboard from '../views/Dashboard.vue';
import Login from '../views/Login.vue';
import '../plugins/vuegapi.js';
Vue.use(VueRouter);
const routes = [
{
path: '*',
redirect: '/',
},
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/login',
name: 'Login',
component: Login,
},
{
path: '/dashboard',
name: 'Dashboard',
component: Dashboard,
meta: {
authRequired: true,
},
},
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.authRequired)) {
if (this.$gapi.currentUser()) {
next();
} else {
alert('You must be logged in to see this page');
next({
path: '/login',
});
}
} else {
next();
}
});
export default router;
I am getting: vue-router.esm.js?8c4f:2314 TypeError: Cannot read property '$gapi' of undefined.
Anyone can point me to right direction? I am able to use this plugin in .vue files but not in another plain .js, suspecting that this $gapi exists only as Vue instakce property/method? As I am beginner I do not know how to import it properly.
if you wanna access Vue instance inside your router use router.app instead of this
change this line :
this.$gapi.currentUser()
to this:
router.app.$gapi.currentUser()
you can read more about Router Instance Properties in : https://router.vuejs.org/api/#router-instance-properties

How to change VueRouter source file dynamicly?

Hello i have a project it contain multiple role (VueJs+Laravel), i'm using laravel as a back-end and vuejs as a front-end,
i have three diffrent role (User,Modirator,Editor).
this is my code in app.js
// VueRouter
import VueRouter from 'vue-router';
import routes from './routes.js';
Vue.use(VueRouter);
var router = new VueRouter({
mode: 'history',
routes
})
this is my routes file:
let routes = [
// General
{ path: '/about', component: require('./components/Home/About.vue').default },
{ path: '/pasword-change', component: require('./components/ChangePassword.vue').default },
// User
{ path: '/User', component: require('./components/User/Dashboard.vue').default },
// Modirator
{ path: '/Modirator', component: require('./components/Modirator/Dashboard.vue').default },
// Editor
{ path: '/Editor', component: require('./components/Editor/Dashboard.vue').default },
// Error
{ path: '*', component: require('./components/Errors/404.vue').default} },
]
export default routes
after login i want to check it in back-end as a ajax request if the role is user use (routes-user.js) elseif is a modirator use (routes-mod.js) else (routes.js).
i dont want to show /user /modirator /editor in client, but i want to check after login and each one show role component in root url /.
thanks for help.
thanks for help....
I tested something similar to your requirement for normal component passing and lazy loading component in Vuex and this works. Below is my code what I am trying to do is have a variable 'unauthorized' and based on which I an loading different component using javascript ternary operator or javascript template string.
import Vue from 'vue'
import Router from 'vue-router'
import Auth from './views/Auth.vue'
import Board from './views/Board.vue'
Vue.use(Router)
let unauthorized = true;
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/auth',
name: 'authenticate',
component: unauthorized ? Auth : Board
},
{
path: '/',
name: 'home',
component: () => import(`./views/${unauthorized ? 'Auth.vue': 'Board.vue'}`)
}
]
})
Specific Solution
As per your requirement, you can store a variable('access-type') in local storage based on whether you log in as 'moderator' or 'user' or 'editor' and then fetch it in router.js file and use template string feature to conditionally change the component path.
Do let me know if you need more help.
You could add meta data to your routes to solve the problem and the check the meta data before you're entering a route:
{ path: '/about', component: require('./components/Home/About.vue').default },
{ path: '/pasword-change', component: require('./components/ChangePassword.vue').default },
// User
{ path: '/User', component: require('./components/User/Dashboard.vue').default, meta: {authorize: ["Admin"]} },
Then add the following method to you router:
router.beforeEach((to, from, next) => {
const { authorize } = to.meta
// get currently logged in user (in my case it's coming from vuex)
const currentUser = store.getters['authentication/user']
if (!currentUser && to.path !== '/login') {
// not logged in so redirect to login page with the return url
return next({ path: '/login', query: { returnUrl: to.path } })
}
if (authorize) {
// check if route is restricted by role
if (authorize.length && !authorize.some(r => currentUser.roles.includes(r))) {
// role not authorised so redirect to home page
return next({ path: '/' })
}
}
next()
})

Vuejs Router, conditional loading of JavaScript Code

I am integrating Vue Router into my application.
Within one of my components, I am using some js code which I do not want to load or be present when on another route?
Example
compA.vue
<script>console.log('hello')</script>
app.com/a -> I should see console log Hello.
app.com/b -> when I access this I should not see hello in the console.
EDIT: Clarifying based on the responses.
I have two components, each with own lifecycle hooks so I do not need to set logic to fire the function based on components...
If a user visits compA and the function fires and creates some side effects, when I visit compB I would like there to be no side effects similar to how a traditional route would work, because it would get the new code and render the page once more.
You could use the path variable accessible through $router in vue. Open your vue devtools, click on your component and click on $route on the righthandside. Here you can see all the variables accessible through $route
Example:
mounted() {
// console.log will only run on route '/a'
if (this.$route.path === '/a') {
console.log('Hello World)
}
}
If $route throws an error. You need to define this in your main.js
import router from './router'
new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
in router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Login from '#/app/Login/Login'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Login',
component: Login
}
]
})
you can add some meta data to your routing config:
const router = new VueRouter({
routes: [
{
path: '/a',
component: compA,
meta: { doLog: true }
},
{
path: '/b',
component: compA,
meta: { doLog: false }
},
]
})
and then you can use this.$route.meta.doLog in your component:
created() {
if(this.$route.meta.doLog) {
console.log('hello');
}
}

How to use component-nesting with vue-router?

I'm pretty new to Vue and I just can't find a good way how to use nested components alongside with vue-router.
What I have so far (some not-important code omitted):
index.html
<body>
<div id="app">
<router-view></router-view>
</div>
app.js
const router = new VueRouter({
routes: [{ path: '/login', component: Login }]
})
const app = new Vue({
router,
}).$mount('#app')
components/Login.vue
<template>
<h1>Please log in</h1>
</template>
This works perfectly well - I navigate to /login and it shows me the message in h1 tag. If I create more components, like Register or ResetPassword and add them to the router, it still works well. But the problem is that there is some repeating code in those components (for example, I want all the auth-related pages to have blue background) so I'd like to somehow create a "parent" component, that would define stuff that is same for all the "children" components. Something like:
Auth component (makes the page-background blue)
-> Login component (shows the login form)
-> Register component (shows the registration form)
I know I can do this through route's "children":
const router = new VueRouter({
routes: [
{ path: '/', component: Auth, children: [
{ path: '/login', component: Login }
{ path: '/register', component: Register }
]}
]
})
But with this configuration, there is the main route path: '/', which is completely wrong - I don't want it here - I don't want the Auth component to be used "standalone" - I want it just as a "wrapper" for the nested components.
What is the best way to solve this problem?
The way I've solved this issue is to use a base path redirect.
{ path: '', redirect: '/to/path' },
in your case it would be
const router = new VueRouter({
routes: [
{
path: '/',
component: Auth,
children: [
{ path: '', redirect: '/login' },
{ path: '/login', component: Login },
{ path: '/register', component: Register }
]
}
]
})
This ensures that

Categories

Resources