Vue named views with lazy loading - vue.js

I am trying to create my routes, but I want them to all use the default router-view in my app.
Looking at the documentation:
https://router.vuejs.org/guide/essentials/named-views.html
I should be able to target views by doing something like this:
const routes = [
{
path: "/",
name: "home",
component: {
default: Home
},
},
]
I want to do this with a child, so I did this:
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: Categories,
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: { default: ProductList },
],
},
],
},
I get no compile errors, but when navigating to /categories/televisions it only shows the Categories component, not the ProductList.
So my first question is, can children target app level router-view?
I also tried to add a new router-view like this:
<router-view />
<router-view name="root" />
and then updated my routes to this:
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: Categories,
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: { root: ProductList },
},
],
},
But this didn't work either.
If it is possible to do this, then my next question, which is where I am heading.
Can I use lazy loaded components and target named/default router-views?
For example, I have this function:
const lazyLoad = (name) => {
return () => import(`../views/${name}/${name}.component.vue`);
};
Which I call from my routes like this:
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: lazyLoad("categories"),
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: lazyLoad("product-list"),
},
],
},
Can I do it like this?
{
path: "/categories",
name: "categories",
meta: {
title: "Categories",
},
component: lazyLoad("categories"),
children: [
{
path: ":slug",
name: "product-list",
meta: {
title: "Categories",
},
component: { default: lazyLoad("product-list") },
},
],
},
and target the root router-view?

Related

Vue-router multiple active routes

Using vue-router, we have a nav menu which works, but we need an additional route to be recognized as "active" for the first nav item.
However the user starts their journey at "account/" (the root), which we show the same content for "/profile" as we don't intend on having actual homepage content to live in "account/".
Nav items:
account/profile ---> Needs class "router-link-active" for both "account/" and "account/profile" routes
account/plan
account/receipts
Routes:
const routes = [
{
path: '/account/',
component: ProfileBase,
children: [
{ path: '', name: 'AppHome', component: ProfileHome }
]
},
{
path: '/account/profile',
component: ProfileBase,
children: [
{ path: '', name: 'ProfileHome', component: ProfileHome },
]
},
{
path: '/account/plan',
component: PlanBase,
children: [
{ path: '', name: 'PlanHome', component: PlanHome },
{ path: 'cancel', name: 'PlanCancel', component: PlanCancel }
]
},
{
path: '/account/receipts',
component: ReceiptsBase,
children: [
{ path: '', name: 'ReceiptsList', component: ReceiptsList },
{ path: ':receiptID', name: 'ReceiptsDetail', component: ReceiptsDetail, props: true }
]
}
]

Nuxt SSR routing problem - [vue-router] Duplicate named routes definition

I am unable to fix the warnings displayed on the console:
this is my routes/index.js
module.exports = [
{
name:'shop-page',
path: '/sklepy/:id',
component: 'pages/shop-page.vue'
},
{
name: 'shops',
path: '/sklepy',
component: 'pages/shops-list-page.vue'
},
{
name: 'categories',
path: '/kategorie',
component: 'pages/category-list-page.vue'
},
{
name: "category-page",
path: '/kategorie/:id',
component: 'pages/category-page.vue'
},
{
name: 'rules',
path: '/regulamin',
component: 'pages/rules-page.vue'
},
{
name: 'privacy policy',
path: '/polityka-prywatnosci',
component: 'pages/privacy-policy-page.vue'
},
{
name: 'new password',
path: '/new-password',
component: 'pages/new-password-page.vue'
},
{
name: 'cookies policy',
path: '/polityka-cookies',
component: 'pages/cookies-page.vue'
},
{
name: 'email-confirmed',
path: '/email-confirmed',
component: 'pages/email-confirmed-page.vue'
},
]
And this is my nuxt.config.js
const routes = require('./routes/index.js')
export default {
css: [
'#/static/css/styles.css',
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
{ src: "#/plugins/filters.js" },
{ src: "#/plugins/axios.js" }
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/tailwindcss
'#nuxtjs/tailwindcss',
'#nuxtjs/composition-api/module'
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
// https://go.nuxtjs.dev/pwa
'#nuxtjs/pwa',
'#nuxtjs/proxy',
'#nuxtjs/dotenv'
],
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
proxy: true
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
},
proxy: {
'/api/': {
target: process.env.VUE_APP_ROOT_API,
pathRewrite: { '^/api': '' }
}
},
router: {
extendRoutes(nuxtRoutes, resolve) {
routes.forEach((route) => {
nuxtRoutes.push({
name: route.name,
path: route.path,
component: resolve(__dirname, route.component)
})
})
}
}
}
these problems probably cause that when I reload the page from url:
http://localhost:3000/shops/4kom
(then click F5, refresh the page), the following appears:
http://localhost:3000/shop-page
Please, help.
Ok, the solution is:
the name cannot be the same as component.
you don't need to loop routes inside nuxt.config.js. try this.
routes/index.js
const extendRoutes = (routes, resolve) => {
routes.push(
{
name:'shop-page',
path: '/sklepy/:id',
component: 'pages/shop-page.vue'
},
{
name: 'shops',
path: '/sklepy',
component: 'pages/shops-list-page.vue'
},
{
name: 'categories',
path: '/kategorie',
component: 'pages/category-list-page.vue'
},
{
name: "category-page",
path: '/kategorie/:id',
component: 'pages/category-page.vue'
},
{
name: 'rules',
path: '/regulamin',
component: 'pages/rules-page.vue'
},
{
name: 'privacy policy',
path: '/polityka-prywatnosci',
component: 'pages/privacy-policy-page.vue'
},
{
name: 'new password',
path: '/new-password',
component: 'pages/new-password-page.vue'
},
{
name: 'cookies policy',
path: '/polityka-cookies',
component: 'pages/cookies-page.vue'
},
{
name: 'email-confirmed',
path: '/email-confirmed',
component: 'pages/email-confirmed-page.vue'
},
);
};
export default extendRoutes;
nuxt.config.js
import extendRoutes from "./routes/index.js";
export default {
router: {
extendRoutes
},
}

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
}
]
}
];

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

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,
},
},
],
});