[Vuejs]-Vue cant pass params on this.$router.push

0👍

In your router file, you are using the same path for both the parent and child route, remove the / from the child component otherwise, it will be treated as the root path.

{
    // student login
    path: '/login',
    name: 'login',
    component: () => import('layouts/student/MainLayout.vue'),
    children: [
      { path: 'login', name: 'Login page', component: () => import('pages/student/LogInPage.vue')}
    ],
    meta: { preventLoginUser: true },
    props: true
  },

Note that this will generate the route as /login/login.

If you need to use /login, change the child route as

{
    // student login
    path: '/login',
    component: () => import('layouts/student/MainLayout.vue'),
    children: [
      { path: '', name: 'login', component: () => import('pages/student/LogInPage.vue')}
    ],
    meta: { preventLoginUser: true },
    props: true
  },

0👍

How to use

You only need to use the children key when you want to create nested routes for a parent route. If you are defining a single route, like in this case, then the use of the children key is unnecessary. So in the above example, you can define the path, name, component, and meta parameters as follows:

{
  path: '/login',
  name: 'login',
  component: () => import('layouts/student/LogInPage.vue'),
  meta: { preventLoginUser: true },
  props: true
}

Call it:

this.$router.push({ name: 'login' }); // because "name: 'login'" in route

Parameters in Route

I don’t know what your "data" parameter means in your example. If you want to use a variable in the route, you need to do it like this:

{
  path: '/login/:myparameter',
  name: 'login',
  component: () => import('layouts/student/LogInPage.vue'),
  meta: { preventLoginUser: true },
  props: true
}

Call it:

this.$router.push({ name: 'login', params: { myparameter: '1' } });

Run function before call Route –> "Guard"

If the purpose of the parameter was to check whether the user who calls it is logged in, then there is a better solution for that. You can declare your own logic before every route to determine how the route should run. For example, for the /login route, if you want it to automatically redirect to the /admin route if the user is already logged in.

// in this code, the isLoggedIn() declare your authentication logic, return true if logged and false if not

const routes = [
  {
    path: '/login',
    name: 'login',
    component: () => import('layouts/student/LogInPage.vue'),
    meta: { preventLoginUser: true },
    props: true
  },
  // ...
]

const router = new VueRouter({
  routes
})

router.beforeEach((to, from, next) => {
  // if call "login", but logged
  if (to.name === 'login' && isLoggedIn()) {
    // redirect to "admin"
    next('/admin')
  }
  // if not...
  else {
    // continue redirect to called route
    next()
  }
})

Example from Vue Router

Why need MainLayout.vue?

There is a significant difference between Layout and Page. I would put them in separate folders from the beginning: /layouts and /pages.

If MainLayout.vue is a global layout for all your pages, then you can include it separately in LogInPage.vue.

By Vue Router

CamelCase name

Something else I noticed is that the name attribute is always just a name that you can refer to this route later. So you don’t have to remember the URL addresses for the operations, you just request the route named login. If the route name is Login Page, it’s harder to remember off the top of your head, and you’re just making things harder for yourself.

If you still need to use multi-word names, it is worth considering omitting spaces and using the CamelCase format, such as loginPage.

Leave a comment