Tuesday, 29 October 2019

Vue route router-view :key= && nested routes && nested name views

<router-view :key="$route.fullPath"></router-view>

https://stackoverflow.com/questions/52847979/what-is-router-view-key-route-fullpath
https://router.vuejs.org/guide/essentials/nested-routes.html

Nested Routes

Real app UIs are usually composed of components that are nested multiple levels deep. It is also very common that the segments of a URL corresponds to a certain structure of nested components, for example:
/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+
With vue-router, it is very simple to express this relationship using nested route configurations.
Given the app we created in the last chapter:
<div id="app">
  <router-view></router-view>
</div>
const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})
The <router-view> here is a top-level outlet. It renders the component matched by a top level route. Similarly, a rendered component can also contain its own, nested <router-view>. For example, if we add one inside the User component's template:
const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}
To render components into this nested outlet, we need to use the children option in VueRouter constructor config:
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // UserProfile will be rendered inside User's <router-view>
          // when /user/:id/profile is matched
          path: 'profile',
          component: UserProfile
        },
        {
          // UserPosts will be rendered inside User's <router-view>
          // when /user/:id/posts is matched
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})
Note that nested paths that start with / will be treated as a root path. This allows you to leverage the component nesting without having to use a nested URL.
As you can see the children option is just another Array of route configuration objects like routes itself. Therefore, you can keep nesting views as much as you need.
At this point, with the above configuration, when you visit /user/foo, nothing will be rendered inside User's outlet, because no sub route is matched. Maybe you do want to render something there. In such case you can provide an empty subroute path:
const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // UserHome will be rendered inside User's <router-view>
        // when /user/:id is matched
        { path: '', component: UserHome },

        // ...other sub routes
      ]
    }
  ]
})


https://router.vuejs.org/guide/essentials/named-views.html#nested-named-views

Nested Named Views

It is possible to create complex layouts using named views with nested views. When doing so, you will also need to name nested router-view components used. Let's take a Settings panel example:
/settings/emails                                       /settings/profile
+-----------------------------------+                  +------------------------------+
| UserSettings                      |                  | UserSettings                 |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
| | Nav | UserEmailsSubscriptions | |  +------------>  | | Nav | UserProfile        | |
| |     +-------------------------+ |                  | |     +--------------------+ |
| |     |                         | |                  | |     | UserProfilePreview | |
| +-----+-------------------------+ |                  | +-----+--------------------+ |
+-----------------------------------+                  +------------------------------+
  • Nav is just a regular component
  • UserSettings is the view component
  • UserEmailsSubscriptionsUserProfileUserProfilePreview are nested view components
NoteLet's forget about how the HTML/CSS should look like to represent such layout and focus on the components used.
The <template> section for UserSettings component in the above layout would look something like this:
<!-- UserSettings.vue -->
<div>
  <h1>User Settings</h1>
  <NavBar/>
  <router-view/>
  <router-view name="helper"/>
</div>
The nested view components are omitted here but you can find the complete source code for the example above here.
Then you can achieve the layout above with this route configuration:
{
  path: '/settings',
  // You could also have named views at the top
  component: UserSettings,
  children: [{
    path: 'emails',
    component: UserEmailsSubscriptions
  }, {
    path: 'profile',
    components: {
      default: UserProfile,
      helper: UserProfilePreview
    }
  }]
}
A working demo of this example can be found here.

No comments:

Post a comment