Ivan Cabrera
Ivan Cabrera

Reputation: 417

How to reuse a named view with a nested nested route in Vue?

I have searched in lots of parts of Internet (stackoverflow,vue documentation, blogs, etc.) and I haven´t found the solution that I need. So, the issue is the following:

routes.js

 {
    path:'/',
    components:{
        allPageView:LytSPA
    },
    meta:{
        requiresAuth:true
    },
    children:[
        {
            path:'',
            name:'admin',
            components:{
                sectionView:AdminDashboard
            }
        },
        {
            name:'admin.users',
            path:'usuarios',
            components:{
                sectionView:Users
            },
            children:[
                {
                    name:'admin.users.create',
                    path:'crear', 
                    components:{
                        sectionView:UsersCreateEdit
                    }
                }
            ]
        }]}

So, the paths are: / , /usuarios and /usuarios/crear.

My views are: App.vue (with a named view), LytSPA.vue (with a named view), AdminDashboard.vue, Users.vue, UsersCreateEdit. So, I have 2 node views and 3 leaf views.

App.vue

<template>
<router-view name="allPageView"></router-view></template>

LytSPA.vue

<template>
<div>
    <header>
        <header-view></header-view>
    </header>
    <transition name="slide-left-aside">
        <aside v-show="!collapsed">
            <aside-view @collapse="collapseAside"></aside-view>
        </aside>
    </transition>
    <transition name="slide-expand-button">
        <b-button @click="collapseAside(false)" id="btnExpand" v-show="collapsed">
            <font-awesome-icon icon="chevron-right"/>
        </b-button>
    </transition>
    <section id="sectionSPA" :class="{collapsed: collapsed}">
        <breadcrumb-view></breadcrumb-view>
        <router-view name="sectionView" key="$route.fullPath"></router-view>
    </section>
</div></template>

As you can see, in LayoutSPA.vue I dropped my main views in the container sectionView, thus:

And here comes the problem, when the path is /usuarios/crear, it either doesn´t load the UsersCreateEdit view or it keeps the last one (Users.vue). However, the routing is working because I put a redirect validation for unknown URLs, since the url usuarios/crear doesn´t change so that's work but doesn´t load the view.

I have already worked of this way with UI-Router in AngularJS and there wasn´t any problem because it works with inheritance of states, but I want to know if exists any way to do the same in Vue???

Note: I have an alternative solution but I don´t like it, because I have to put the admin.users.create route as a sibling of admin.users and it works but I need that it be nested because I need to retrieve the matched routes to build my breadcrumb and I don't want to parse the path to build it.

path /usuarios/crear with incorrect view (Users)

Upvotes: 2

Views: 2671

Answers (2)

Guillermo Ver&#243;n
Guillermo Ver&#243;n

Reputation: 238

I have faced the same problem and I found the solution in the following post in dev.to.

If you want to show the list component and the form component in separate views. You can create a root component which wraps both the list and form:

User.vue (wrapper)

<template>
    <router-view></router-view>
</template>

And you must have something like that in your routes.js file

//...omitted for brevity
const routes = [
{
    path: "/users",
    component: User,
    children: [
      { path: "/", component: ListUsers, name: "user-list" },
      { path: "new", component: FormUsers, name: "user-form" }
    ]
  }
];
//...omitted for brevity

If you don't want to create a new file for the root component, you can use the render method:

{
    path: "/users",
    component: {
     render(c) { // render the wrapper component
        return c("router-view");
      }
    },
    children: [
      {
        path: "",
        component: ListUsers
      },
      {
        path: "new",
        component: FormUsers
      }
    ]
}

Upvotes: 1

Alex
Alex

Reputation: 1423

When you add child route admin.users.create, it's mean that in parent route with name admin.users component must contain own <router-view> with name sectionView.

You can find that picture in vue-router documentation

/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

The component User contains its own <router-view>, where rendering components Profile or Posts

So, add <router-view name="sectionView"></router-view> into component Users, or move route to higher level.

Upvotes: 0

Related Questions