Defining routes in a separate file and using them inside index.js - javascript

I have this routes inside my index.js
import {
createRouter,
createWebHistory
}
from '#ionic/vue-router';
import {
RouteRecordRaw
}
from 'vue-router';
const routes = [{
path: '',
redirect: '/tabs'
}, {
path: '/tabs',
component: () => import('../views/tabs/TabRoot.vue'),
children: [{
path: '',
redirect: '/tabs/home'
}, {
path: '/tabs/home',
component: () => import('../views/tabs/Home.vue')
},
]
},
//Sell
{
path: '/sell',
component: () => import('../views/pages/sell/Sell.vue')
},
//Categories
{
path: '/trending',
component: () => import('../views/pages/Trending.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
and i would like to define the follwoing routes isnide others.js file and have this inside
{
path: '/crud_ui_landing_vehicles',
component: () => import('../views/pages/sell/categories/Vehicles.vue')
},
{
path: '/crud_ui_landing_properties',
component: () => import('../views/pages/sell/categories/Properties.vue')
},
The imported routes should be used inside const routes array object.
How can i define and import the routes file?

Using the spread operator
// others.js
export const others = [...]
import { others } from './others.js'
const routes = [
...others,
👆
{
path: ...,
component: ...
},
...
]

Related

How to solve vue-router Uncaught TypeError?

I am trying to upgrade my project from vue 2 to vue 3. But constantly I getting errors.
This is my new console error:
vue-router.mjs:3499 Uncaught TypeError: Cannot read properties of undefined (reading 'location')
And this is line 3499:
push(routerHistory.location).catch(err => {
if ((process.env.NODE_ENV !== 'production'))
warn('Unexpected error when starting the router:', err);
});
The file is in node_modules (front/node_modules/vue-router/dist/vue-router.mjs)
How can I fix it?
I am using: "vue-router": "^4.1.2",
main.js:
import { library } from '#fortawesome/fontawesome-svg-core';
import {faSpinner} from '#fortawesome/free-solid-svg-icons';
import SortedTablePlugin from 'vue-sorted-table/src';
import { FontAwesomeIcon, FontAwesomeLayers } from '#fortawesome/vue-fontawesome';
import { BootstrapVue3 } from 'bootstrap-vue-3';
import { createApp, h } from 'vue';
import App from './App.vue';
import './registerServiceWorker';
import router from './router';
library.add(
faSpinner,
);
const app = createApp({
render: () => h(App),
});
app.use(router);
app.use(BootstrapVue3);
app.use(SortedTablePlugin);
app.component('font-awesome-icon', FontAwesomeIcon);
app.component('font-awesome-layers', FontAwesomeLayers);
app.mount('#app');
router/index.js
// import Vue from 'vue';
import { createRouter } from 'vue-router';
import FormStep from '#/components/FormStep.vue';
import DualTable from '#/components/DualTable.vue';
import ListTable from '#/components/ListTable.vue';
import CaptureScreen from '#/components/CaptureScreen.vue';
import StageScreen from '#/components/StageScreen.vue';
import TopScreenConfig from '#/components/TopScreenConfig.vue';
import EmailCapture from '#/components/EmailCapture.vue';
import store from '#/store';
// Vue.use(VueRouter);
const routes = [
{
path: '/form/:form/step-:step',
name: 'FormStep',
component: FormStep,
}, {
path: '/form/:form/step-:step/:related',
component: FormStep,
}, {
path: '',
name: 'ListTable',
component: ListTable,
}, {
path: '/:status.html',
component: ListTable,
}, {
path: '/personal/',
component: ListTable,
}, {
path: '/personal/:status.html',
component: ListTable,
}, {
path: '/aggregator/',
component: ListTable,
}, {
path: '/aggregator/:status.html',
component: ListTable,
}, {
path: '/config/case_and_process_types.html',
component: DualTable,
}, {
path: '/run_stage/:id/',
name: 'StageScreen',
component: StageScreen,
}, {
path: '/capture/:id/',
name: 'CaptureScreen',
component: CaptureScreen,
}, {
path: '/capture_from_email/:email/:id/',
name: 'EmailCaptureScreen',
component: EmailCapture,
}, {
path: '/config/screens/:id.html',
name: 'ScreenConfig',
component: TopScreenConfig,
}, {
path: '/config/:model/',
name: 'ConfigList',
component: ListTable,
}, {
path: '/emails/',
name: 'Emails',
component: ListTable,
},
];
const router = createRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth) && !store.state.user.isAuthenticated) {
next('/login/');
return;
}
next();
});
export default router;
Is it about Vue.use(VueRouter); ?
You need to replace the mode: 'history' with history: createWebHistory() property, as the mode property is deprecated in version 4.
For more resources.
https://router.vuejs.org/guide/migration/index.html#new-history-option-to-replace-mode
This is a resource for migration from Vue 2 to Vue 3
https://router.vuejs.org/guide/migration/index.html
The router instance should be created in this way :
import { createRouter,createWebHashHistory } from 'vue-router';
....
const router = createRouter({
history: createWebHashHistory(),
base: process.env.BASE_URL,
routes,
});

vue-router 4 '/:pathMatch(.*)*' not working?

hello guys I want to ask about vue-router.
when I use vue 2 if there is a page that doesn't match, I use path: '*' to go to my page404 but in vue 3 it's been replaced with '/:pathMatch(.)' after i tried it the warning in console disappeared but i just got a blank page and it doesn't point to my page404. did i miss something? I'm newbie with vue 3
here is the version I'm using:
vue: ^3.0.0
vue-router: ^4.0.0-0
and this is my index.js
import { createRouter, createWebHistory, RouterView } from 'vue-router'
const routes = [
{
path: '/',
redirect: '/login',
component: RouterView,
children: [{
path: '/login',
component: () => import('#/views/login/Login.vue'),
}]
},
{
path: '/:pathMatch(.*)*',
component: () => import('#/views/page404/Page404.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
You can try to write it like this
{
path: "/:pathMatch(.*)*",
redirect: "/404"
},
{
path: "/404",
name: "404",
component: () => import("#/views/page404/Page404.vue")
}

Vue3 Redirect with dynamic property

I have this configuration in my router.ts:
{
path: "/admin/operations/job-allocation/:id",
name: "JobAllocation",
component: () =>
import(
"#/views/admin/operations/job-allocation/index.vue"
),
children: [
{
path: "",
redirect:
"/admin/operations/job-allocation/:id/operatives",
},
{
path: "/admin/operations/job-allocation/:id/operatives",
name: "JobAllocationOperatives",
alias: "Operatives",
component: () =>
import("#/views/common/Operatives.vue"),
},
]
}
When I visit the path: /admin/operations/job-allocation/1 I want to go to /admin/operations/job-allocation/1/operatives.
But in this setup it goes to /admin/operations/job-allocation/:id/operatives (the :id as a literal string of ':id' instead of being replaced by the number 1.
I'm hoping to use the router to do this, instead of using a 'mounted' hook to do the redirect at the JobAllocation component.
Is this even possible? I did not find this senario in the official Vue3 Router docs.
Use the object form of redirect to specify the route by name, so that the parameters are automatically passed along:
export default createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: HelloWorld
},
{
path: '/admin/operations/job-allocation/:id',
name: 'JobAllocation',
props: true,
component: () => import('#/views/admin/operations/job-allocation/index.vue'),
children: [
{
path: '',
redirect: {
name: 'JobAllocationOperatives', 👈
},
},
{
path: '/admin/operations/job-allocation/:id/operatives',
name: 'JobAllocationOperatives',
alias: 'Operatives',
component: () => import('#/views/common/Operatives.vue')
}
]
}
]
})
demo

Vue route only works after visiting root URL first

I'm using Vue Router to redirect https://example.com/foo to https://example.com/foo/randomID.
This only works if the root URL https://example.com are visited first - otherwise a direct call of https://example.com/foo results in a 404 not found.
I can't figure out the root cause of this.
What I've tried so far:
New build
Update NPM packages
Clean install on server
Clean Site Data via Chrome Dev Tools
router.js:
import Vue from 'vue'
import Router from 'vue-router'
import Head from 'vue-head'
import Home from '#/views/Home'
import CheckLogin from '#/views/CheckLogin'
import { isNil } from 'lodash'
import store from '#/store'
Vue.use(Router)
/* If you don't know about VueHead, please refer to https://github.com/ktquez/vue-head */
Vue.use(Head, {
complement: process.env.VUE_APP_TITLE
})
/* If you don't know about VueRouter, please refer to https://router.vuejs.org/ */
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/home',
name: 'home',
component: Home,
meta: {
authNotRequired: true
}
},
{
path: '/check-login',
name: 'check-login',
component: CheckLogin,
meta: {
authNotRequired: true
}
},
{
path: '/login',
name: 'login',
component: () =>
import(
/* webpackChunkName: "client-chunk-login" */ '#/views/Login.vue'
),
meta: {
authNotRequired: true
}
},
{
path: '/products',
name: 'products',
component: () =>
import(
/* webpackChunkName: "client-chunk-products" */ '#/views/Products.vue'
)
},
{
path: '/item/:id',
name: 'item',
props: true,
component: () =>
import(
/* webpackChunkName: "client-chunk-product-details" */ '#/views/Item.vue'
)
},
{
path: '/list/:id',
name: 'list',
props: true,
component: () =>
import(
/* webpackChunkName: "client-chunk-product-details" */ '#/views/List.vue'
),
meta: {
authNotRequired: true
}
},
{
path: '/list',
name: 'listredirect',
props: true,
component: () =>
import(
/* webpackChunkName: "client-chunk-product-details" */ '#/views/Listredirect.vue'
),
meta: {
authNotRequired: true
}
},
{ path: '*', redirect: '/home' }
]
})
/**
* Handle user redirections
*/
// eslint-disable-next-line consistent-return
router.beforeEach((to, from, next) => {
if (
!(to.meta && to.meta.authNotRequired) &&
isNil(store.state.authentication.user)
) {
const path =
store.state.authentication.user === null ? '/login' : '/check-login'
return next(`${path}?redirectUrl=${to.path}`)
}
next()
})
export default router
The vue.config.production.js:
const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') // eslint-disable-line
.BundleAnalyzerPlugin
const PrerenderSPAPlugin = require('prerender-spa-plugin') // eslint-disable-line
const prerenderedRoutesList = ['/login', '/home', '/']
// TODO stats raus aus dist -> plugin ganz raus?!
module.exports = {
configureWebpack: {
plugins: [
/* Refer to https://www.npmjs.com/package/webpack-bundle-analyzer for more details */
new BundleAnalyzerPlugin({
analyzerMode: 'disabled',
generateStatsFile: true
}),
/* See https://github.com/chrisvfritz/prerender-spa-plugin for more details */
new PrerenderSPAPlugin({
// Required - The path to the webpack-outputted app to prerender.
staticDir: path.join(__rootDirname),
// Required - Routes to prerender.
routes: prerenderedRoutesList
})
]
}
}
The redirect component:
<template>
<div>
{{ this.$router.push('/list/new') }}
</div>
</template>
Any ideas on how to fix this issue are appreciated.
Maybe you could use Vue Router redirect function? Eg.
routes: [
{ path: '/foo', redirect: to => {
// code you need...
return "/foo/id";
}}
]
basically you need to redirect your 404 hits to index.html, then the path will resolve correctly. Read here for more information
You can use redirect in the vue-router
routes: [
{ path: '/foo', redirect: '/foo/:randomId' }
]
this.$route.params.randomId will be in the component.
Have a look at docs here

Vue router doesn't recognize :lang as a param

I have the following code:
import Router from 'vue-router';
let mainRoutes = [
{path: '/first', component: () => import('./pages/First')},
{path: '/second', component: () => import('./pages/Second')},
{path: '/third', component: () => import('./pages/Third')},
];
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
scrollBehavior() {
return {x: 0, y: 0}
},
routes: [
{
path: '/:lang',
component: () => import('./layouts/Main'),
children: mainRoutes,
meta: {requiresAuth: true, permissions: true}
},
{
path: '*',
component: () => import('#/pages/errors/404')
}
]
})
router.beforeEach((to, from, next) => {
if (!to.query.lang) {
to.query.lang= 'ru';
next({ path: to.path, query: to.query });
} else {
next();
}
});
export default router
What I want:
Every time some route is entered, I want the vue-router to check whether it has the lang param or not. If not, I want it to place 'ru' in there, if yes then proceed and show the page with the necessary lang (the part which i18n is responsible for).
The problem is that it doesn't recognize ':lang' as a param for the children routes for some reason, so if I try to go to 'test.test/ru', it returns the lang param ok, but if I try 'test.test/ru/first' it doesn't see it and returns 404.
Everything works in case I put :lang param before every child component but it's not really practical. Is there any better way to solve this issue?
With a code like this you should get the effect you want.
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import VueRouter from 'vue-router';
import Router from './Router.vue';
import En from './translation/En.vue';
import Ru from './translation/Ru.vue';
Vue.use(VueI18n);
Vue.use(VueRouter);
Vue.use(VueBus);
const messages = {
en: En,
ru: Ru,
};
const i18n = new VueI18n({
fallbackLocale: 'ru',
locale: 'ru',
messages,
});
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/:lang',
component: {
render: (h) => h('router-view'),
},
children: [your children route],
});
router.beforeEach((to, from, next) => {
const { lang } = to.params;
if (!['en', 'fr'].includes(lang)) {
return next(i18n.locale);
}
if (i18n.locale !== lang) {
i18n.locale = lang;
}
return next();
});
I'm not sure but without i18n I think it's that :
...
router.beforeEach((to, from, next) => {
const { lang } = to.params;
if (!['en', 'ru'].includes(lang)) {
route.params.lang = 'ru';
router.push({ name: route.name });
}
});
I've finally found a solution!
If you have some param in the main route, your children routes shouldn't start with a '/' symbol, but simply with the correct route, for instance
let mainRoutes = [
{path: 'first', component: () => import('./pages/First')},
{path: 'second', component: () => import('./pages/Second')},
{path: 'third', component: () => import('./pages/Third')},
];
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
scrollBehavior() {
return {x: 0, y: 0}
},
routes: [
{
path: '/:lang',
component: () => import('./layouts/Main'),
children: mainRoutes,
meta: {requiresAuth: true, permissions: true}
},
]
})

Categories

Resources