Vue router - When replacing route view renders on top of another - vue.js

When trying to replace the current /login route with another route, it seems that the new route gets rendered on top of the last, making it behave strange.
router.js
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Main Page',
component: MainPage,
redirect: 'front-page',
children: [
{
path: 'front-page',
name: 'Front page',
component: FrontPage,
meta: {
requireAuth: true,
},
},
{
path: 'home',
name: 'Home page',
component: HomePage,
meta: {
requireAuth: true,
},
},
],
},
{
path: '/profile',
name: 'Profile page',
component: UserProfilePage,
meta: {
requireAuth: true,
},
},
{
path: '/login',
name: 'Login page',
component: LoginPage,
meta: {
requireAuth: false,
},
},
{
path: '/register',
name: 'Registration page',
component: RegistrationPage,
meta: {
requireAuth: false,
},
},
],
});
login.vue
result() {
if (this.loginQuery.sessionToken) {
this.setAuthToken(this.loginQuery.sessionToken);
this.$router.replace('/front-page');
}
},

Your problem may come from redirection,It's no necessary to set 'home' as a default route by using redirect,try code below:
const router = new Router({
mode: 'history',
routes: [
{
name: 'Main Page',
component: MainPage,
children: [
{
path: '/front-page',
name: 'Front page',
component: FrontPage,
meta: {
requireAuth: true,
},
},
{
path: '/',
name: 'Home page',
component: HomePage,
meta: {
requireAuth: true,
},
},
],
},
{
path: '/profile',
name: 'Profile page',
component: UserProfilePage,
meta: {
requireAuth: true,
},
},
{
path: '/login',
name: 'Login page',
component: LoginPage,
meta: {
requireAuth: false,
},
},
{
path: '/register',
name: 'Registration page',
component: RegistrationPage,
meta: {
requireAuth: false,
},
},
],
});

Related

vue-router hashMode not rendring component of some paths

I am using vue3 and vue-router.
routes
import { createRouter, createWebHashHistory } from 'vue-router'
import InitialView from '../views/InitialView.vue'
import store from '#/store/index.js'
import { defineAsyncComponent } from 'vue'
import SkeletonCard from '../skeletons/SkeletonCard.vue'
import NotFound from '#/components/NotFound.vue'
// const UsersList = defineAsyncComponent({
// loader: () => import("#/components/UserList.vue"),
// loadingComponent: SkeletonCard,
// delay: 0
// })
const RolesList = defineAsyncComponent({
loader: () => import('../components/RoleList.vue'),
loadingComponent: SkeletonCard,
delay: 0
})
const ClientsList = defineAsyncComponent({
loader: () => import('../components/ClientsList.vue'),
loadingComponent: SkeletonCard,
delay: 0
})
const TasksList = defineAsyncComponent({
loader: () => import('../components/TasksList.vue'),
loadingComponent: SkeletonCard,
delay: 0
})
// const MyTasksList = defineAsyncComponent({
// loader: () =>
// loadingComponent: SkeletonCard,
// delay: 0
// })
const ActivityList = defineAsyncComponent({
loader: () => import('../components/UserActivity.vue'),
loadingComponent: SkeletonCard,
delay: 0
})
const routes = [
{
path: '/',
alias: '/#',
name: 'main',
component: InitialView,
children: [{
path: '/',
alias: 'login',
name: 'login',
component: () => import('../components/LogIn.vue')
}]
},
{
path: '/u',
name: 'u',
component: () => import('../views/MainView.vue'),
children: [
{
path: '/no-access',
name: 'no_access',
component: () => import('../components/NoAccess.vue')
},{
path: '/users',
alias: 'users',
name: 'users',
component: () => import('../views/UsersView.vue'),
children: [{
path: 'create-user',
name: 'create_user',
component: () => import('../components/UserCreate.vue'),
meta: {
protected: true,
breadcrumb: {
title: 'create user',
path: [{
text: 'list',
route: '/u/users/list'
}, {
text: 'create',
route: '/u/users/create-user'
}]
}
},
}, {
path: '',
alias: 'list',
name: 'users_list',
component: () => import("#/components/UserList.vue"),
meta: {
breadcrumb: {
title: 'users',
action: true,
actionUrl: '/u/users/create-user',
path: [{
text: 'list',
route: '/u/users/list'
}]
}
}
},
{
path: 'edit/:editUserId',
name: 'edit_user',
meta: {protected: true},
component: () => import('../components/UserCreate.vue'),
props: true,
}
]
}, {
path: 'roles',
name: 'roles',
component: () => import('../views/RoleView.vue'),
children: [{
path: 'create-role',
name: 'create_role',
component: () => import('../components/RoleCreate.vue'),
meta: {
breadcrumb: {
title: 'roles',
path: [{
text: 'list',
route: '/u/roles/list'
}, {
text: 'create',
route: '/u/roles/create-role'
}]
},
protected: true
},
}, {
path: 'list',
alias: '',
name: 'roles_list',
component: RolesList,
meta: {
breadcrumb: {
title: 'roles',
action: true,
actionUrl: '/u/roles/create-role',
path: [{
text: 'list',
route: '/u/roles/list'
}]
}
}
}, {
path: 'edit/:editRoleId',
name: 'edit_role',
meta: {
breadcrumb: [{
title: 'edit role',
path: [{
text: 'list',
route: '/u/roles/list'
}, {
text: 'edit',
route: '/u/roles/edit/:editRoleId',
}]
}],
protected: true
},
component: () => import('../components/RoleCreate.vue'),
props: true
}]
},{
path: 'clients',
name: 'clients_list',
component: () => import('../views/ClientView.vue'),
children: [{
path: 'list',
alias: '',
name: 'clients_list',
component: ClientsList,
meta: {
breadcrumb: {
title: 'clients',
action: true,
actionUrl: '/u/clients/create-client',
path: [{
text: 'list',
route: '/u/clients/list'
}]
}
}
}, {
path: 'create-client',
name: 'create_client',
component: () => import('../components/ClientCreate.vue'),
meta: {
breadcrumb: {
title: 'create client',
path: [{
text: 'list',
route: '/u/clients/list'
}, {
text: 'create',
route: '/u/clients/create-client'
}]
},
protected: true,
}}
]}, {
path: '/tasks',
name: 'tasks',
component: () => import('../views/TasksView.vue'),
children: [{
path: '',
alias: 'list',
name: 'tasks_list',
component: TasksList,
meta: {
breadcrumb: {
title: 'tasks',
action: true,
actionUrl: '/u/tasks/create-task',
path: [{
text: 'list',
route: '/u/tasks/list'
}]
}
}
}, {
path: 'create-task',
name: 'create_task',
component: () => import('../components/TasksCreate.vue'),
meta: {
breadcrumb: {
title: 'create task',
path: [{
text: 'list',
route: '/u/tasks/list'
}, {
text: 'create',
route: '/u/tasks/create-task'
}]
},
protected: true
}
}]
}, {
path: '/my-tasks',
name: 'my_tasks',
component: () => import('../views/MyTasksView.vue'),
children: [{
path: '',
name: 'my_tasks_list',
component: () => import('../components/MyTasksList.vue'),
meta: {
breadcrumb: {
title: 'my tasks',
path: [{
text: 'list',
route: '/u/my-tasks/list'
}]
}
}
}]
}, {
path: 'activity',
name: 'activity',
component: ActivityList,
meta: {
breadcrumb: {
title: 'activity',
path: [{
text: 'list',
route: '/u/activity/'
}]
},
protected: true
},
}]
},
{
path: '/:pathMatch(.*)',
name: 'not-found',
component: NotFound
}
]
const router = createRouter({
history: createWebHashHistory(process.env.BASE_URL),
routes
})
router.beforeEach((to, from)=>{
if (to?.meta?.protected) {
console.log(to, from)
const userRights = store.getters['rights/getUserRights']
const allow = userRights?.some((right) => right?.code_name == to?.name)
if (!allow) return { name: 'no_access'}
}
})
export default router
http://localhost:8080/#/ is login page if valid login in performed user gets redirected to my_tasks_list route
In login page
axios.post('api/login', {
email: this.email,
password: this.pwd
}, {
withCredentials: true,
})
.then((results) => {
if (results?.data?.login == 1) {
this.$router.push({name: 'my_tasks_list'})
}
else {
this.$router.push({name: 'login'})
}
})
.catch(err =>
swal({
text: `Ooops ${err}`
})
)
Everything works fine If I access http://localhost:8080 it immediately redirect me to http://localhost:8080/#/ and if I pass valid login credentials then to my_tasks_list component
if I try to access http://localhost:8080/#/ then I get redirected to login page and if I pass valid login credentials then to my_tasks_list everything seems to work but my_tasks_list isn't rendering actual component.
any help is appreciated

Signin page redirect to 404 when first load vue js 2.0

When the application starts, I am setting the default path to users, if authentication fails, then it will navigate to sign in. But it redirects to 404.
const routes = [
{
path: "/signin",
name: "signIn",
component: () => import("#/path"),
},
{
.........
},
{
.......
},
{
path: "/",
redirect: "/users",
component: adminLayout,
//needed for nav gaurd
//meta: { requiresAuth: true },
children: [
{
path: "dashboard",
name: "dashboard",
component: dashboard,
meta: {
title: 'Dashbaord'
}
},
{
path: "users",
component: () => import("path"),
meta: {
title: 'Users'
},
children: [
{
path: "",
component: () => import("path"),
meta: {
title: ''
}
},
{
path: ":id/profile",
component: () => import("path"),
meta: {
title: 'Profile'
}
},
]
},
],
},
{
path: "*",
redirect: "/404",
},
{
// the 404 route, when none of the above matches
path: "/404",
name: "404",
component: () => import("#path"),
},
];
If i set redirect: "/dashboard" or redirect: "/signin",, then it works fine.
Also if I navigate to the right path, like "http://localhost:8080/signin" it will work. But if I only type "http://localhost:8080" hit enter it will go to 404 page
Note : first my users component like this and its works fine
{
path: "users",
component: () => import("path"),
meta: {
title: 'Users'
},
},
{
path: ":id/profile",
component: () => import("path"),
meta: {
title: 'Profile'
},
},
Please help me to understand the issue.

Redirect from beforeEnter causes infitite cycle and does not redirect

I have a problem with the nonworking redirect. I check is the user is logged in and the info is right, but when it comes to redirecting it does not redirect and just goes in this beforeEnter over and over again. Can somebody say what am I doing wrong?
I am presenting here my RouteConfig and the problem with the first beforeEnter.
export const routes: RouteConfig[] = [
{ path: '*', redirect: '/' },
{
path: '/',
component: router_view,
async beforeEnter(to, from, next) {
var hasPermission = await storage.get('state').user.tokens.access;
console.log(!!hasPermission)
if (!!hasPermission && from.fullPath.startsWith('/')) {
return next('profile');
} else {
return next()
}
},
children: [
{
name: 'landing',
meta: { requiresAuth: false },
path: '',
component: require('pages/index').default
},
{
meta: { requiresAuth: true },
path: 'seller',
component: require('pages/seller').default,
children: [
{
path: '',
name: 'profile',
redirect: 'profile'
},
{
path: 'account',
component: require('pages/seller/account').default
},
{
path: 'help/:url?',
component: require('pages/seller/help').default
},
{
path: 'profile',
component: require('pages/seller/profile').default
},
{
path: 'finances/:shop?',
name: 'finances',
props: route => ({
...route.query,
...route.params
}),
component: require('pages/seller/finances').default
},
{
path: 'shop',
component: require('pages/seller/shop').default,
children: [
{
path: '',
redirect: 'main'
},
{
path: 'main',
component: require('pages/seller/shop/main').default
},
// {
// path: 'rating',
// component: require('pages/seller/shop/rating').default
// },
{
path: 'design',
component: require('pages/seller/shop/design').default
},
]
},
{
path: 'invoices',
redirect: { name: 'invoices-send' },
component: require('pages/seller/invoices/index').default,
children: [
{
path: 'send',
name: 'invoices-send',
component: require('pages/seller/invoices/send').default,
},
{
path: 'return',
name: 'invoices-return',
component: require('pages/seller/invoices/return').default
},
{
path: 'create-send',
component: require('pages/seller/invoices/createInvoice').default,
},
{
path: 'create-return',
component: require('pages/seller/invoices/createInvoice').default,
},
]
},
{
path: 'products',
component: router_view,
children: [
{
path: '',
redirect: 'all'
},
{
path: 'new',
component: require('pages/seller/products/new').default,
children: [
{
path: '',
component: require('pages/seller/products/new/createproduct').default
},
]
},
{
path: 'id/:productid/edit',
component: require('pages/seller/products/new').default,
children: [
{
path: '',
name: 'edit-product',
props: route => ({ ...route.params, ...route.query }),
component: require('pages/seller/products/new/createproduct').default
},
{
path: 'sku',
name: 'edit-product-sku',
component: require('pages/seller/products/new/createsku').default,
},
]
},
{
path: 'invoices',
redirect: { name: 'invoices-send' }
},
{
path: 'id/:productid',
component: require('pages/seller/products/_productid').default,
children: [
{
path: 'main',
name: 'product-page-solo',
component: require('pages/seller/products/_productid/main').default
},
// {
// path: 'reviews',
// component: require('pages/seller/products/_productid/reviews').default
// },
// {
// path: 'statistics',
// component: require('pages/seller/products/_productid/statistics').default
// },
{
path: 'printlabels',
name: 'product-labels-solo',
component: require('pages/seller/products/_productid/printlabels').default
},
]
},
{
path: 'stickers',
name: 'products-stickers',
component: require('pages/seller/products/stickers').default,
},
{
path: ':table',
name: 'product-list',
component: require('pages/seller/products/index').default,
props: _ => ({
tabletype: _.params.table
}),
beforeEnter(to, from, next) {
if (to.params.table === 'invoices') {
return next({ name: 'invoices' });
} else {
next();
}
},
children: [
{
path: 'id/:productid',
component: require('pages/seller/products/_productid').default,
children: [
{
path: 'main',
name: 'product-page',
component: require('pages/seller/products/_productid/main').default
},
// {
// path: 'reviews',
// component: require('pages/seller/products/_productid/reviews').default
// },
// {
// path: 'statistics',
// component: require('pages/seller/products/_productid/statistics').default
// },
{
path: 'printlabels',
name: 'product-labels',
component: require('pages/seller/products/_productid/printlabels').default
},
]
},
]
}
]
}
]
},
{
meta: { requiresAuth: false },
name: 'signin',
path: '/signin',
component: router_view,
children: [
{
path: '',
name: 'signin',
component: require('pages/signin/index').default
},
{
path: 'restore',
component: router_view,
children: [
{
path: '',
component: require('pages/signin/restore/index').default
},
{
path: 'password',
component: require('pages/signin/restore/newpassword').default,
beforeEnter(to, from, next) {
if (from.fullPath.startsWith('/confirm'))
return next();
else
return next('/');
}
}
]
}
]
},
{
path: 'confirm',
meta: { requiresAuth: false },
component: require('pages/confirm/index').default,
beforeEnter(to, from, next) {
const path = from.fullPath ? from.fullPath : from.path;
if (path === '/signin' || path === '/signup' || path === '/signin/' || path === '/signup/' || path === '/' || path === '/signin/restore' || path === '/signin/restore/'
|| (from.path.startsWith('/confirm') && from.query === to.query)
|| to.query.from === 'account'|| to.query.from === 'restore')
return next();
else
return next('/');
}
},
{
name: 'signup',
path: 'signup',
meta: { requiresAuth: false },
component: router_view,
children: [
{
path: '',
name: 'signup',
component: require('pages/signup/index').default
},
{
path: 'social',
component: require('pages/signup/social').default
},
]
},
{
meta: { requiresAuth: false },
path: 'terms-of-use',
component: require('pages/terms-of-use').default
}
]
}
];

How do I redirect to login if the path is '/' or '/login'?

How do I redirect if the the path is '/' or '/login'. I was thinking of adding another object with '/' and component will still be login but I don't know if that's the right way.
Here is my router.
const router = new Router({
mode: 'history',
linkExactActiveClass: 'active',
routes: [
{
name: 'dashboard',
path: '/dashboard',
component: Dashboard,
meta: {
requiresAuth: true
}
},
{
name: 'profile',
path: '/profile',
component: Profile,
meta: {
requiresAuth: true
}
},
{
name: 'login',
path: '/login',
component: Login,
meta: {
requiresVisitor: true
}
},
{
name: 'logout',
path: '/logout',
component: Logout,
meta: {
requiresAuth: true
}
}
]
});
if you want to redirect with '/' or '/login' so you can try this one
const router = new Router({
mode: 'history',
linkExactActiveClass: 'active',
routes: [
{
path: '',
redirectTo: '/login',
pathMatch: 'full'
},
{
name: 'dashboard',
path: '/dashboard',
component: Dashboard,
meta: {
requiresAuth: true
}
},
{
name: 'profile',
path: '/profile',
component: Profile,
meta: {
requiresAuth: true
}
},
{
name: 'login',
path: '/login',
component: Login,
meta: {
requiresVisitor: true
}
},
{
name: 'logout',
path: '/logout',
component: Logout,
meta: {
requiresAuth: true
}
}
]
});

Accessing authenticated route with vue-router

Ive been struggling with a bug that occurs occasionally within my VueJs2 application.
After i login and im authenticated within my app and data is stored within Vuex then im unable to access an authenticated route when clicking on the link.
The problem is with the 'profile' route which is on my navbar when logged in. If i refresh the browser then it works and im able to click the link and view the component.
The problem is with the beforeEach and it failing to get the Vuex authenticated as true.
This is my current router setup.
import Vue from 'vue'
import VueRouter from 'vue-router'
import { store } from '../store/index'
import SiteIndex from '#/components/home/Index.vue'
import AuctionIndex from '#/components/auction/Index.vue'
import ViewVehicle from '#/components/vehicle/View.vue'
import Login from '#/components/authentication/Login.vue'
import Register from '#/components/registration/Register.vue'
import ForgotPassword from '#/components/authentication/Forgot.vue'
import Cart from '#/components/cart/Index.vue'
import UserProfile from '#/components/user/Profile.vue'
import AboutUs from '#/components/site/About.vue'
import Faq from '#/components/site/Faq.vue'
import HowItWorks from '#/components/site/HowItWorks.vue'
import ContactUs from '#/components/site/ContactUs.vue'
import Terms from '#/components/site/Terms.vue'
import Error404 from '#/components/site/Error404.vue'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{ path: '/', redirect: '/index' },
{ path: '/logout', redirect: '/login' },
{
path: '/index',
name: 'home',
component: SiteIndex,
meta: {
breadcrumb: 'Home',
displayBreadCrumb:false
}
},
{
path: '/auction',
name: 'auction',
component: AuctionIndex,
meta: {
breadcrumb: {
label: 'Auction',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/auction/:slug/:vehicle_id',
component: ViewVehicle,
meta: {
displayBreadCrumb:true
}
},
{
path: '/cart',
component: Cart,
meta: {
requiresAuth: true,
breadcrumb: {
label: 'Basket',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/login',
component: Login,
meta: {
breadcrumb: {
label: 'Login',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/register',
component: Register,
meta: {
breadcrumb: {
label: 'Register',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/forgot',
component: ForgotPassword,
meta: {
breadcrumb: {
label: 'Forgot Password',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/profile',
component: UserProfile,
meta: {
requiresAuth: true,
breadcrumb: {
label: 'My Profile',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/terms',
component: Terms,
meta: {
breadcrumb: {
label: 'Terms and conditions',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/howitworks',
component: HowItWorks,
meta: {
breadcrumb: {
label: 'How it works',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/faq',
component: Faq,
meta: {
breadcrumb: {
label: 'Frequently asked questions',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/about',
component: AboutUs,
meta: {
breadcrumb: {
label: 'About us',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '/contactus',
component: ContactUs,
meta: {
breadcrumb: {
label: 'Contact us',
parent: 'home'
},
displayBreadCrumb:true
}
},
{
path: '*',
component: Error404
}
],
linkActiveClass: 'active',
mode: 'history'
})
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if(requiresAuth && !store.getters.isLoggedIn) {
next('/login');
} else {
next();
}
})
export default router