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
Related
I hope this is a quick one.
I have this mapping that looks like this:
const routes = routeOptions.map((route) => {
return {
children: route?.children?.map((child) => {
return {
...{
path: child.path,
name: child.name,
meta: child.meta,
alias: child.alias,
},
component: () =>
import(
/* webpackPrefetch: true */
/* webpackChunkName: "[request]" */
`../views/${child.name
.replace(" ", "-")
.toLowerCase()}/${child.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
}),
...{
path: route.path,
name: route.name,
meta: route.meta,
redirect: route.redirect,
},
component: () =>
import(
/* webpackChunkName: "[request]" */
`../views/${route.name
.replace(" ", "-")
.toLowerCase()}/${route.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
});
Then I can set my routeOptions like this:
const routeOptions: RouteOptions[] = [{
path: "/account",
name: "account",
meta: {
title: "Account",
},
redirect: {
name: "sign-in",
},
children: [{
path: "sign-in",
name: "sign-in",
meta: {
title: "Sign in",
},
},
{
path: "join",
name: "join",
meta: {
title: "Join",
},
},
{
path: "add-password",
name: "add-password",
meta: {
title: "Add password",
},
},
{
path: "forgot-password",
name: "forgot-password",
meta: {
title: "Forgot password",
},
},
{
path: "reset-password",
name: "reset-password",
meta: {
title: "Reset password",
},
},
],
},
{
path: "/crew",
name: "staff",
meta: {
title: "Crew",
},
redirect: {
name: "staff-account",
},
children: [{
path: "account",
name: "staff-account",
meta: {
title: "Account",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "demos",
name: "staff-demos",
meta: {
title: "Demos",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "leader-boards",
name: "staff-leader-boards",
meta: {
title: "Leader boards",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "search",
name: "staff-search",
meta: {
title: "Search",
authorize: ["Venue Staff", "Venue Manager"],
},
},
{
path: "stories",
name: "staff-stories",
meta: {
title: "Stories",
authorize: ["Venue Staff", "Venue Manager"],
},
},
],
},
{
path: "/404",
name: "not-found",
meta: {
title: "Page not found",
},
},
{
path: "*",
name: "layout",
meta: {},
children: [{
path: "/business/live-better",
name: "blog",
meta: {
title: "Partner Blog",
},
children: [{
path: ":title",
name: "blog",
}, ],
},
{
path: "/business/live-better/:title",
name: "blog-post",
},
{
path: "/brands",
name: "brand-list",
meta: {
title: "Brands",
},
},
{
path: "/brands/:brandSlug",
name: "brand-details",
meta: {
title: "Details",
},
},
{
path: "/categories",
redirect: {
name: "categories"
},
},
{
path: "/categories/:categorySlug",
redirect: {
name: "product-list"
},
},
{
path: "/categories/:categorySlug/:productId/:productTitle",
redirect: {
name: "product-details"
},
},
{
path: "/products",
name: "categories",
meta: {
title: "Products",
},
},
{
path: "/products/:categorySlug",
name: "product-list",
meta: {
title: "Products",
},
},
{
path: "/products/:categorySlug/:productId/:productTitle",
name: "product-details",
meta: {
title: "Details",
},
},
{
path: "/favourites",
name: "favourites",
meta: {
title: "Your favourites",
},
},
{
path: "/feedback",
name: "consumer-feedback",
meta: {
title: "Your feedback",
authorize: [],
},
},
{
path: "/venues/:venueSlug/theatres",
name: "theatre-list",
meta: {
title: "Theatres",
},
},
{
path: "/venues/:venueSlug/theatres/:theatreSlug",
name: "theatre-details",
meta: {
title: "Theatre",
},
},
{
path: "/venues",
name: "venue-list",
meta: {
title: "Venues",
},
},
{
path: "/venues/:venueSlug",
name: "venue-details",
meta: {
title: "Details",
},
},
{
path: "/search",
name: "search",
meta: {
title: "Search results",
},
},
{
path: "*",
name: "home",
meta: {
title: "Home",
},
},
],
},
];
Most of these work, but if you take a look at this section here:
{
path: "/categories",
redirect: { name: "categories" },
},
{
path: "/categories/:categorySlug",
redirect: { name: "product-list" },
},
{
path: "/categories/:categorySlug/:productId/:productTitle",
redirect: { name: "product-details" },
},
I want these to redirect to other named views.
The way my mapping works at the moment, is that it takes the name and looks in the views folder for a matching template, but these routes don't have templates because they are just redirects.
Does anyone know what I can do to my code to get it to work with these?
I did it like this:
const createChildRoutes = (children) => {
return children?.map((child) => {
const childRoute = {
path: child.path,
name: child.name,
meta: child.meta,
alias: child.alias,
redirect: child.redirect,
};
if (child.name) {
return {
...childRoute,
component: () =>
import(
/* webpackPrefetch: true */
/* webpackChunkName: "[request]" */ `../views/${child.name
.replace(" ", "-")
.toLowerCase()}/${child.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
} else {
return childRoute;
}
});
};
const routes = routeOptions.map((route) => {
const mainRoute = {
path: route.path,
name: route.name,
meta: route.meta,
alias: route.alias,
redirect: route.redirect,
};
if (route.name) {
return {
children: createChildRoutes(route?.children),
...mainRoute,
component: () =>
import(
/* webpackPrefetch: true */
/* webpackChunkName: "[request]" */ `../views/${route.name
.replace(" ", "-")
.toLowerCase()}/${route.name
.replace(" ", "-")
.toLowerCase()}.component.vue`
),
};
} else {
return {
children: createChildRoutes(route?.children),
...mainRoute,
};
}
});
Here i can get id of company by #click event whenever i choose company, It's get id accord company.
And now i want my Sidebar(navbar) get id accord url corresponding whenever i #click option in sidebar(product,sale,...) it gonna be :"companies/48/products" for example
{
path: "",
name: "Company",
component: () =>
import ("../views/DashboardLayout.vue"),
meta: { requiresAuth: true },
props: true,
children: [{
path: "companies",
component: () =>
import ("../views/CompaniesLayout.vue"),
children: [{
path: "",
component: () =>
import ("../companies/views/CompaniesDashboard.vue"),
},
{
path: ":companyId/contacts",
component: () =>
import ("../views/Contacts.vue"),
},
{
path: ":companyId/products",
component: () =>
import ("../views/Products.vue"),
},
{
path: ":companyId/sales",
component: () =>
import ("../views/Sales.vue"),
},
{
path: ":companyId/fees",
component: () =>
import ("../views/Fees.vue"),
},
{
path: ":companyId/employees",
component: () =>
import ("../views/Employees.vue"),
},
{
path: ":companyId/setting",
component: () =>
import ("../views/Setting.vue"),
},
{
path: "create",
component: () =>
import ("../companies/views/RegisterCompany.vue"),
},
],
},
{
path: "/dashboard",
component: () =>
import ("../views/WelcomeDashboard.vue"),
},
{
path: "/profile",
component: () =>
import ("../profile/views/Profile.vue"),
},
{
path: "products",
component: () =>
import ("../views/Products.vue"),
},
{
path: "sales",
component: () =>
import ("../views/Sales.vue"),
},
{
path: "fees",
component: () =>
import ("../views/Fees.vue"),
},
{
path: "employees",
component: () =>
import ("../views/Employees.vue"),
},
{
path: "setting",
component: () =>
` import ("../views/Setting.vue"),`
},
],
},
];
Here my route
links: [
{
to: "/dashboard",
icon: "mdi-view-dashboard",
text: "Dashboard",
},
{
to: `/companies/1/sales`,
icon: "mdi-currency-usd",
text: "Sales",
},
{
to: `/companies/1/contacts`,
icon: "mdi-domain",
text: "Contacts",
},
{
to: `/companies/1/products`,
icon: "mdi-cube-outline",
text: "Products",
},
{
to: `/companies/1/fees`,
icon: "mdi-calculator-variant-outline",
text: "Fees",
},
{
to: `/companies/1/employees`,
icon: "mdi-account-supervisor",
text: "Employees",
},
{
to: `/companies/1/setting`,
icon: "mdi-cog",
text: "Company setting",
},
],
Here my data link. I set hard id = 1 to sure it right. it's supposed to companies/${companyId}/setting for example. If you want any code to compare, tell me.
Tks everyone so much..
Bonus loom for everyone know my issue
https://www.loom.com/share/32228acb3d6e4e77b496f9791d730879
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.
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
}
]
}
];
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,
},
},
],
});