I'm working on a Vue.js webapp. Recently I realized then when I want to change route (going home) from a Vuex action, it takes a lot of time and never end. It take 4600 MB RAM and 70% CPU.
Here is the indicted code:
impostaSelezionabili: ({ commit,dispatch }, payload) => {
commit("associazioniSelezionabiliImpostate", payload)
const prefe = payload.prefe
if (payload.associazioni.length == 1) {
commit("associazioneScelta", payload.associazioni[0].codAssociazione)
dispatch("toolbarManager/setToolbarVisibility", true, {root: true})
router.push({ path: '/' })
}
},
Everything works perfectly without router line, when I add router.push({ path: '/' }) it gets the problem.
Is there a way to solve?
Router config / Routes:
export const router = new Router({
mode: 'history',
routes: [
{ path: '/', component: HomePage, name: "Home", meta: "Home" },
{ path: '/servizi', component: ServiziPage, meta: "Servizi" },
{ path: '/servizi/:id', component: ServizioPage, meta: "Servizi" },
{ path: '/login', component: LoginForm},
{ path: '/corsi', component: Corsi, meta: "Corsi" },
{ path: '/corsidisponibili', component: Corsi, meta: "Corsi disponibili" },
// otherwise redirect to home
{ path: '*', redirect: '/', meta: "Home" }
]
});
Make sure that your router exists and that is not an import of vue-router. You need to use the router that you constructed with the new Router().
But I think that is the best way to solve it - that navigating inside a component after a Promise returned by that action will be resolved because in the current case your action isn`t pure.
Related
I have an Angular 8 app. In my router module I have something like this
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: ':code', component: CodeComponent },
{ path: 'not-found', component: NotFoundComponent},
{ path: '**', component: NotFoundComponent }
];
The problem here is that when I access (for an example) /not-found the component CodeComponent activates, but not the NotFoundComponent.
I want to distinguish /not-found page from parametrized /:code
Invert the order of your routes in your array so the 'not-found' definition comes before the ':code' definition. Like this
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'not-found', component: NotFoundComponent},
{ path: ':code', component: CodeComponent },
{ path: '**', component: NotFoundComponent }
];
How to use a guard to move to next rule of route instead of redirect to specific route?
for example, I have some routes:
routes: [
{ path: '/', component: Main },
{ path: '/about', component: About },
{ path: '/:product', component: Product },
{ path: '*', component: NotFoundException }
]
and in Product component I have beforeRouteEnter function like that:
beforeRouteEnter(to, from, next) {
const question = checkIfExist(to.params.product);
if (question) { next(); return;}
next();
}
if the product not exist then it should be redirect to NotFoundException component. in the stackoverflow example I see only example with redirect to specific url (like login) which is not helpful.
When I given url: '/some' then vue check if:
is / ? no => next route.
is /about ? no => next route.
is /:product ? no => next route.
display NotFoundException component.
You can reference the next route by route name.
First, name your exception route
routes: [
{ path: '/', component: Main },
{ path: '/about', component: About },
{ path: '/:product', component: Product },
{ path: '*', name: 'notFound', component: NotFoundException }
]
Then, create a variable which stores your beforeEnter Logic
const productExists = (to, from, next) => {
const question = checkIfExist(to.params.product);
if (question) { next(); return;}
next({
name: "notFound"
});
}
Add the route guard to the routes that you want to guard
routes: [
{ path: '/', component: Main },
{ path: '/about', component: About },
{ path: '/:product', component: Product, beforeEnter: productExists },
{ path: '*', name: 'notFound', component: NotFoundException }
]
I want to pass the last route into my router when I'm in /login to redirect the user when is logged to desired route.
So the user go to /payment I redirect to /login and when the authentication is ok I want to redirect the user to payement
Here is my router.js :
import ...
Vue.use(Router)
let router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/payment',
name: 'payment',
component: Payment,
meta: {
requiresAuth: true
}
},
{
path: '/my-account',
name: 'my-account',
component: MyAccount,
meta: {
requiresAuth: true
}
}
]
})
router.beforeEach((to, from, next) => {
console.log('Before Each Routes')
if(to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
console.log('Logged in')
next()
return
}
console.log(to.fullPath)
next({
path: '/login',
params: { nextUrl: to.fullPath }
})
return
} else {
console.log(to.fullPath)
next()
}
})
export default router
So I set some console.log and I got this :
if I go directly to /login, Output :
Before Each Routes
/login
Then if I go to /payment, Output :
Before Each Routes
/payment
Before Each Routes
/login
So now when I go in my login component and I use this.$route.params.nextUrl it's undefined. The next() parameter doesn't exist and I don't know why.
What I'm doing wrong ?
It looks like you're confusing two different mechanisms: params and query. Params have to be integral to the url, like /user/:id while query params are appended automatically.
You want this:
next({
path: '/login',
query: {
nextUrl: to.fullPath,
}
})
Related reading: https://router.vuejs.org/api/#route-object-properties
Tristan's approach above is the best when passing a url as a parameter. However, in normal cases we're passing something like an id so you can use this:
next({ name: 'account', params: { id: 3 } });
Add the replace option to prevent the navigation from appearing in the history:
next({ name: 'account', params: { id: 3 }, replace: true });
I'm using vue-router 3.1.6.
I'm having problems to make my http://localhost:8080/myapps/config route load. If I use http://localhost:8080/myapps everything works ok and I get a list of my apps. But when I want to access an app config through http://localhost:8080/myapps/config it loads the content of /myapps again. However, the url in my browser shows the correct path /myapps/config.
I have been checking the routher for some hours but everything seems to be ok. Could anybody shed some light?
My router file:
import Vue from 'vue'
import Router from 'vue-router'
const MyApps = () => import('../views/app/subviews/MyApps');
const AppKeyValue = () => import('../views/app/subviews/AppKeyValue');
import MainView from '../views/app/MainView'
Vue.use(Router)
export default new Router({
mode: 'history',
routes:
[
{
path: '/',
component: MainView,
redirect: 'myapps',
children:
[
{
path: 'myapps',
component: MyApps,
meta:
{
requiresAuth: true,
breadcrumb: 'My Apps'
},
children:
[
{
path: 'config',
component: AppKeyValue,
meta:
{
requiresAuth: true,
breadcrumb: 'App configuration'
}
},
]
},
]
},
]
})
Everything works ok if I don't use child routes:
export default new Router({
mode: 'history',
routes:
[
{
path: '/',
component: MainView,
redirect: 'myapps',
children:
[
{
path: 'myapps',
component: MyApps,
meta:
{
requiresAuth: true,
title: 'message.ecommerce',
breadcrumb: 'My Apps'
},
},
{
path: 'myapps/config',
component: AppKeyValue,
meta:
{
requiresAuth: true,
title: 'message.ecommerce',
breadcrumb: 'App configuration'
}
}
]
}
]}
You didn't post your *.vue components, but I assume you're missing <router-view> in the second level component.
Example:
MainView is mapped to / and has 1 children route (/myapps). You're probably using <router-view> in your MainView.
MyApps is mapped to myapps as a children of the /-route and has 1 children route (/config).
Add a <router-view to your MyApps.vue to let it display its children (which is just /config in your case).
Similarly, a rendered component can also contain its own, nested <router-view>.
https://router.vuejs.org/guide/essentials/nested-routes.html#nested-routes
BTW: That's also why your second router config is working: The main route has two children (/myapps and /myapps/config), which both get displayed by the MainView's <router-view>.
Here is a working example from the documentation:
https://jsfiddle.net/nazgul_mamasheva/zrcLe9z7/1/
I have my routes as define below:
const router = new Router({
base: '/',
mode: 'history',
routes: [
{
path: '/',
redirect: `${DEFAULT_LOCALE}`,
},
{
path: '/:locale?',
component: AppTemplate,
children: [
{
path: 'home',
name: 'home',
component: () => import('#/views/Home.vue'),
meta: {
title: 'Home',
}
}
{
path: 'about',
name: 'about',
component: () => import('#/views/About.vue'),
meta: {
title: 'About',
},
},
{
path: 'contact',
name: 'contact',
component: () => import('#/views/Contact.vue'),
meta: {
title: 'Contact',
},
},
{
path: '*',
redirect: { path: '/' },
},
],
},
{
path: '*',
redirect: { path: '/' },
},
],
});
export default router;
I use :locale for app translation. It is optional because empty locale is for default language. My problem here is even if locale is present, all the links to other pages are without the locale, if that makes sense. For eg, example.com/about is in Italian and example.com/en/about is in English. But which ever URL it is, the links present on the page always points to contact or home page as example.com/contact and example.com/home. Is there a way to fix this? Or is there an easier way to use app translation from URL. I am using vue-i18n for the translation. Thanks
For such configuration I think you have to pass param to make it work:
<router-link :to="{name: 'contact', params: {locale: $route.params.locale} }">
https://jsfiddle.net/3gx4hak5/
Also maybe router-link append attribute will do the trick for you: https://router.vuejs.org/api/#append
Setting append prop always appends the relative path to the current path. For example, assuming we are navigating from /a to a relative link b, without append we will end up at /b, but with append we will end up at /a/b.
<router-link :to="{ path: 'relative/path'}" append></router-link>