VueJS addRoutes add more children routes - vue.js

Implementing language switcher and have this last (hope so) missing puzzle.
I have these routes defined:
routes: [
{
path: '/',
redirect: `/en`,
},
{
path: '/:lang',
component: {
render: h => h('router-view')
},
children: [
{
path: '',
name: 'home',
component: Home,
},
],
},
],
And I have some routes coming from backend, I adding these routes to existing like this:
fetchRoutes({commit}) {
axios.get( `${process.env.VUE_APP_API_DOMAIN}/wp-json/api/v1/routes/`).then( r => r.data ).then(routes => {
routes.forEach( (route) => {
router.addRoutes([
{
path: `${route.path}`,
name: `${route.path}`,
component: () => import(/* webpackChunkName: 'pages' */ `./views/${route.component}.vue`),
props: route.props,
},
]);
} );
});
},
This is fine for non-children routes. But I need to put these routes under path: '/:lang', as children.

Related

Vuejs stop rendering component after adding transition in vue router

Vuejs stopped rendering components after I added a transition in the children route of my dashboard layout when I checked the error there was no error and no warnings but whenever I am reloading the page the components render, and the same functionality works in the same application in my login layouts children route when I am going in the network I am getting 304 HTTP error
this is my index router
import { createRouter, createWebHistory } from "vue-router";
// importing Dashboard routes
import DashboardRoutes from "./Dashboard/index.js";
import store from "#/store/store.js";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
// redirecting the root to the login welcome page
redirect: { name: "login" },
},
{
// creating a group path for all the login pages
path: "/login",
name: "login",
redirect: { name: "welcome" },
component: () => import("../components/Pages/Login/LoginMain.vue"),
//checking the condition if user is logged in or not and redirecting
beforeEnter: (_, _2, next) => {
if (store.state.login.isLoggedIn) {
next("/dashboard");
} else {
next();
}
},
children: [
{
path: "/welcome",
name: "welcome",
component: () =>
import("../components/Pages/Login/Childrens/WelCome.vue"),
},
{
path: "/austria-login",
name: "austria-login",
component: () =>
import("../components/Pages/Login/Childrens/AustriaLogin.vue"),
},
{
path: "/sms-login",
name: "sms-login",
component: () =>
import("../components/Pages/Login/Childrens/SmsLogin.vue"),
},
{
path: "/enter-tpn",
name: "enter-tpn",
component: () =>
import("../components/Pages/Login/Childrens/EnterTpn.vue"),
//chcking the condition of phone and social security token is entered
beforeEnter: (_, _2, next) => {
if (!store.state.login.phoneVerified) {
next("/sms-login");
} else {
next();
}
},
},
],
},
// using Dashboard Routes
...DashboardRoutes,
],
scrollBehavior(_, _2, savedPosition) {
if (savedPosition) {
window.scrollTo(savedPosition);
} else {
window.scrollTo(0, 0);
}
},
});
export default router;
this is my dashboard children routes
import AppointmentRoutes from "./Appointment"; // importing appointment children routes
import SettingRoutes from "./Setting";
import store from "#/store/store";
const DashboardRoutes = [
{
// router group for all the dashboard views
path: "/dashboardMain",
name: "dashboardMain",
component: () => import("../../components/Pages/DashBoard/IndexMain.vue"),
beforeEnter: (_, _2, next) => {
if (store.state.login.isLoggedIn) {
next();
} else {
next('/login');
}
},
children: [
{
path: "/dashboard",
name: "dashboard",
component: () =>
import("../../components/Pages/DashBoard/Home/DashBoard.vue"),
props: { sidebar: true },
},
// router for appointments
{
path: "/appointments",
name: "PatientAppoinetments",
redirect: { name: "PatientAppointmentsData" },
component: () =>
import(
"../../components/Pages/DashBoard/PatientAppointment/PatientAppointment.vue"
),
props: { sidebar: true },
// children group for appointments components
children: [...AppointmentRoutes],
},
{
path: "/requests",
name: "Requests",
component: () =>
import(
"../../components/Pages/DashBoard/PatientRequests/PatientRequest.vue"
),
},
{
path: "/medications",
name: "Medications",
component: () =>
import(
"../../components/Pages/DashBoard/PatientMedication/PatientMedication.vue"
),
},
{
path: "/questions",
name: "Questions",
component: () =>
import(
"../../components/Pages/DashBoard/PatientQuestionaries/PatientQuestionaries.vue"
),
},
{
path: "/health-status",
name: "HealthStatus",
component: () =>
import(
"../../components/Pages/DashBoard/PatientHealth/PatientHealth.vue"
),
},
{
path: "/diagnostic-center",
name: "PatientDiagnosticCenter",
component: () =>
import(
"../../components/Pages/DashBoard/PatientDiagnostic/PatientDiagnosticCenter.vue"
),
},
{
path: "/vaccination",
name: "PatientVaccination",
component: () =>
import(
"../../components/Pages/DashBoard/PatientVaccination/PatientVaccination.vue"
),
},
{
path: "/setting",
name: "Setting",
redirect: { name: "AccountSetting" },
component: () =>
import("#/components/Pages/DashBoard/Setting/SettingIndex.vue"),
children: [...SettingRoutes],
},
{
path: "/chat",
name: "PatientChat",
redirect: { path: "/chat/gautam" },
component: () =>
import(
"../../components/Pages/DashBoard/PatientChat/PatientChat.vue"
),
// children group for chat page
children: [
{
path: "/chat/:name",
name: "chatMessages",
component: () =>
import(
"../../components/Pages/DashBoard/PatientChat/Children/PatientChatmessages.vue"
),
},
],
},
{
path: "/access-log",
name: "AccessLog",
component: () =>
import("#/components/Pages/DashBoard/AccessLog/AccessLog.vue"),
},
{
path: "/my-profile",
name: "MyProfile",
component: () =>
import("#/components/Pages/DashBoard/MyProfile/MyProfile.vue"),
props: { sidebar: true },
},
],
},
];
export default DashboardRoutes;
and this is DahboardMain where i want to renders my dashboard children pages
but i am getting the blank the black screen children area whenere i am going to any route except page reload
I tried to remove beforeEnter guard from the routes and I also removed all the code from the dashboard layout except router-view but still getting the black screen
enter image description here this is the image of the blank screen
enter image description here this is showing in the network

Vue Router 4 - nested 404 (not found) routes redirect not working

these are my routes:
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: {},
children: [
{ path: "extensions", component: {} },
{ path: "themes", component: {} },
{ path: ":pathMatch(.*)*", redirect: "extensions" },
],
},
{
path: "/about",
component: {},
children: [
{ path: "experience", component: {} },
{ path: "documents", component: {} },
{ path: ":pathMatch(.*)*", redirect: "experience" },
],
},
{ path: "/:pathMatch(.*)*", redirect: "/projects/extensions" },
];
Expected result:
Navigating to /projects or /projects/asdasd -> redirects to /projects/extensions
Navigating to /about or /about/asdasd -> redirects to /about/experience
Navigating to /asdasdasd -> redirects to /projects/extensions
Current result:
Every incorrect path redirects me to /projects/extensions
I tried many combinations but nothing works as expected, please help.
Redirecting to child route
To redirect /projects to /projects/extensions, add a child route with a blank path that redirects to the target route:
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: () => import("../views/ProjectsView.vue"),
children: [
{
path: "",
redirect: "/projects/extensions", // or use a named route (see below)
},
โ‹ฎ
],
},
}
Getting the redirect target right
When the redirect string is not an absolute path to a route (i.e., /about/experience), the path would be relative to the current route.
For instance, imagine being at /projects/themes and clicking /about/foo. This is how the final route would resolve:
/about/foo matches the wildcard route under /about, which redirects to /projects/themes/experience.
/projects/themes/experience matches the outer wildcard route, which redirects to /projects/extensions.
There are a couple ways to solve this...
Option 1: Use absolute path in redirect string
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: () => import("../views/ProjectsView.vue"),
children: [
{
path: "extensions",
component: () => import("../views/ProjectsExtensions.vue"),
},
{
path: "themes",
component: () => import("../views/ProjectsThemes.vue"),
}, ๐Ÿ‘‡
{ path: ":pathMatch(.*)*", redirect: "/projects/extensions" },
],
},
{
path: "/about",
component: () => import("../views/AboutView.vue"),
children: [
{
path: "experience",
component: () => import("../views/AboutExperience.vue"),
},
{
path: "documents",
component: () => import("../views/AboutDocuments.vue"),
}, ๐Ÿ‘‡
{ path: ":pathMatch(.*)*", redirect: "/about/experience" },
],
}, ๐Ÿ‘‡
{ path: "/:pathMatch(.*)*", redirect: "/projects/extensions" },
]
demo 1
Option 2: Use named route in redirect object
const routes: Array<RouteRecordRaw> = [
{
path: "/projects",
component: () => import("../views/ProjectsView.vue"),
children: [
{
path: "extensions",
๐Ÿ‘‡
name: "proj-ext",
component: () => import("../views/ProjectsExtensions.vue"),
},
{
path: "themes",
component: () => import("../views/ProjectsThemes.vue"),
}, ๐Ÿ‘‡
{ path: ":pathMatch(.*)*", redirect: { name: "proj-ext" } },
],
},
{
path: "/about",
component: () => import("../views/AboutView.vue"),
children: [
{
path: "experience",
๐Ÿ‘‡
name: "about-exp",
component: () => import("../views/AboutExperience.vue"),
},
{
path: "documents",
component: () => import("../views/AboutDocuments.vue"),
}, ๐Ÿ‘‡
{ path: ":pathMatch(.*)*", redirect: { name: "about-exp" } },
],
}, ๐Ÿ‘‡
{ path: "/:pathMatch(.*)*", redirect: { name: "proj-ext" } },
]
demo 2
Named routes are easier to maintain than paths, as (1) they avoid having to enter long paths, and (2) they could be moved without having to refactor paths.

Getting tilde (~) in vue router chunks

I am using webpackChunkName to give names to the build files (chunks). I same two global routes (path: /) and different child routes of each.
After the build, I see can some of the chunks have a tilde sign in them and I havenโ€™t added that. For example
dist/js/AccountManagement~Login~Register.dec3aad2.js
The AccountManagement is in a separate child route and log in and Register are different routes of the same parent route.
Here is my trimmed vue route file
const routes = [
{
path: "/",
component: () => import("#layouts/dashboard.vue"),
children: [
{
path: "/account/:page",
name: "Account",
meta: {
requiresAuth: true,
title: "My Account",
},
component: () => import(/* webpackChunkName: "AccountManagement" */ "#page/profile/MyAccount.vue"),
},
],
},
{
path: "/",
component: () => import("#layouts/headers.vue"),
children: [
{
path: "/login",
name: "Login",
meta: {
requiresAuth: false,
title: "Login - Inline Checkout",
},
component: () => import(/* webpackChunkName: "Login" */ "#page/authentication/Login.vue"),
},
{
path: "/reset-password",
name: "ForgotPassword",
meta: {
requiresAuth: false,
title: "Password Reset - Inline Checkout",
},
component: () => import(/* webpackChunkName: "ForgotPassword" */ "#page/authentication/ForgotPassword.vue"),
},
{
path: "/register",
name: "Register",
meta: {
requiresAuth: false,
title: "Register - Inline Checkout",
},
component: () => import(/* webpackChunkName: "Register" */ "#page/authentication/Register.vue"),
},
],
},
];
All I need is to remove this Tilde sign and unwanted name, in this case, ~Login~Register.

Why does the router link not work the first time?

I have a grpc application, there is authorization. When you start a project, you must be logged in. I decided to add under the login button if you are not registered. But the router does not work. Only at the entrance, go to the registration page. Please help to understand what is the mistake? Why is seemingly blocked?
routes.js
const routes = [
{
path: "/",
component: () => import("layouts/MainLayout"),
children: [
{
path: "",
component: () => import("pages/Index"),
meta: { requireAuth: true }
},
{
path: "/logs",
component: () => import("pages/Logs"),
meta: { requireAuth: true, admin: true }
}
]
},
{
path: "/",
component: () => import("layouts/AuthLayout"),
children: [
{
path: "/welcome",
component: () => import("pages/Auth"),
meta: { guest: true }
},
{
path: "/register",
component: () => import("pages/Register"),
meta: { guest: true }
}
]
}
];
I tried many things, like in Auth.vue:
<q-item to='/register'>Sign Up</q-item>
<router-link tag="a" :to="{path:'/register'}" replace>Go</router-link>
<span #click="callSomeFunc()">Register</span>
...
methods: {
callSomeFunc() {
this.$router.push({ path: "/register" });
}
My router-view in App.vue
for more information github repo
You have duplicate routes in your config - the path / is used on 2 routes. You should fix this.
To prevent unauthorized users to see your protected pages you can add a global navigation guard to your router through the beforeEach hook:
import VueRouter from 'vue-router';
const routes = [
{
path: "/",
component: () => import("layouts/MainLayout"),
meta: { requireAuth: true },
children: [
{
path: "",
component: () => import("pages/Index"),
},
{
path: "logs",
component: () => import("pages/Logs"),
meta: { admin: true }
}
]
},
{
path: "/login",
component: () => import("layouts/AuthLayout"),
children: [
{
path: "",
component: () => import("pages/Auth"),
},
{
path: "/register",
component: () => import("pages/Register"),
}
]
}
];
const router = new VueRouter({
routes
});
router.beforeEach((to, from, next) =>
{
if (to.matched.some(route => route.meta.requireAuth))
{
if (userNotLogged) next('/login');
else next();
}
else next();
});
export default router;
You may also consider reading a more verbose tutorial, e.g. https://www.digitalocean.com/community/tutorials/how-to-set-up-vue-js-authentication-and-route-handling-using-vue-router

How to prevent child routes in Vue.js from losing styles when the page refreshes

My routing for my site works fine but the problem arises when I hit the refresh button.
On a base route for example http://localhost:8080/employers the page or component style remains the same but when I refresh a child route for example http://localhost:8080/employers/google all the style for this component will be lost.
Any help on how to resolve this problem will be appreciated
import Vue from 'vue'
import Router from 'vue-router'
// import store from './store.js'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
component: () => import('./views/Home.vue'),
children: [
{
path: "",
component: () => import("./views/HomePage.vue"),
},
{
path: '/jobs',
name: 'jobs',
component: () => import('./views/JobListings.vue')
},
{
path: '/job/:id',
name: 'job',
component: () => import('./views/JobDetails.vue')
},
{
path: '/login',
name: 'login',
component: () => import('./views/Login.vue')
},
{
path: '/register',
name: 'register',
component: () => import('./views/Register.vue')
},
{
path: '/forgotpassword',
name: 'forgotpassword',
component: () => import('./views/ForgotPassword.vue')
},
{
path: '/verify',
name: 'verify',
component: () => import('./views/Verify.vue')
},
],
},
{
path: '/employer',
component: () => import('#/views/Employers.vue'),
children: [
{
path: '',
component: () => import('./views/Employers/Profile.vue')
},
{
path: 'profile',
component: () => import('./views/Employers/Profile.vue')
},
{
path: 'post',
component: () => import('./views/Employers/PostJob.vue')
},
{
path: 'listings',
component: () => import('./views/Employers/Listings.vue')
},
{
path: 'settings',
component: () => import('./views/Employers/Listings.vue')
},
{
path: 'editresume',
component: () => import('./views/Employers/Listings.vue')
},
{
path: 'closeaccount',
component: () => import('./views/Employers/Listings.vue')
},
]
},
// jobseekers route
{
path: '/jobseeker',
component: () => import('#/views/Jobseekers/Home.vue'),
children: [
{
path: '',
component: () => import('#/views/Jobseekers/Profile.vue')
},
{
path: 'resume',
component: () => import('#/views/Jobseekers/Resume.vue')
},
{
path: 'profile',
component: () => import('#/views/Jobseekers/Profile.vue')
},
{
path: 'settings',
component: () => import('#/views/Jobseekers/Settings.vue')
},
{
path: 'applications',
component: () => import('#/views/Jobseekers/Applications.vue')
},
{
path: 'close',
component: () => import('#/views/Jobseekers/Close.vue')
},
]
},
{
path: '/jobseeker/:page',
component: () => import('#/views/Jobseekers/Profile.vue'),
},
{
path: '/search/:region/:keyword',
component: () => import('./views/JobListings.vue')
},
// not found route
{
path: '*',
name: '404',
component: () => import('./views/404.vue')
}
]
})
export default router
The problem is not with your routes, but how you write your css.
I recommend using a scoped style for in component styling (only this component will use the styles).
if more than one components are going to share styling, you can use css files separately.
I noticed that you are loading the components on-demand.
When you navigate from /employers to /employers/google route, there are some CSS styles from /employers route that are being reused in your /employers/google route.
So when you reload http://localhost:8080/employers/google route, you are unable to obtain the styles from /employers which causes your CSS to break.
My suggestion is to move common styles into one particular file and import it into the main file like App.vue so that they are loaded no matter which component is reloaded.
I'm also the same issue but I already include the CSS globally but it doesn't work,
finally, I try to change the router mode from history to hash it work.
Try in my case it works fine.
const router = new Router({
mode: "hash",
base: process.env.BASE_URL,
routes: []
})
Just add mode:"hash" after carrying out mode:"history", has shown below, and you are good to go
const router = new Router({
mode: "history",
mode: "hash",
routes: []
})