In Vue Router 5, how do named views show a mail list and message detail side by side, and how do they differ from nesting?
answer
- components with an s
- default is the unnamed view
- RouterView name prop
- siblings at one depth
- a missing view renders nothing
basics
~20 sA record's components map (default, detail, ...) fills several RouterViews at the same depth, each selected by its name prop; nested routes instead stack one view inside another. Views without a component for the route render nothing.
solid answer
~40 sA record can set `components` (with an s) instead of `component`: `{ path: '/mail/:folder/:messageId?', components: { default: MessageList, detail: MessageDetail } }`. The layout renders `<RouterView />`, whose name is `default`, and `<RouterView name="detail" />`; each picks its component from the matched record by name. Named views are **siblings at one depth**, filled by one record, while nested routes are **levels**, filled by a parent and a child. A `RouterView` whose name has no entry in the matched record renders nothing, which lets a route omit the detail pane. Nested layouts can use named views too; the named `RouterView` then sits inside the parent component. With named views, the `props` option also becomes a per-view map.
code
ts · 14 linesconst routes = [
{
path: '/mail',
component: () => import('@/views/mail/MailLayout.vue'), // default + detail RouterViews
children: [
{ path: ':folder', components: { default: MessageList } },
{
path: ':folder/:messageId',
components: { default: MessageList, detail: MessageDetail },
props: { default: true, detail: true },
},
],
},
]go deeper
Know the components map with a default key and the name prop on RouterView.
Contrast named views with nested routes and explain what renders when a view has no component.
Combine named views with nested layouts, place each named RouterView at the right depth, and reason about which panes remount.
Choose between peer panes and nested layouts for complex screens so URLs, state lifetimes and layout ownership line up.
## Several outlets, one match A route record normally declares one `component`. With **named views** it declares `components`, an object mapping view names to components: ```ts { path: '/mail/:folder/:messageId?', components: { default: MessageList, detail: MessageDetail, }, } ``` The layout places one `RouterView` per name: ```vue <template> <div class="mail"> <MailFolders /> <RouterView /> <RouterView name="detail" /> </div> </template> ``` - A `RouterView` without a `name` prop is the `default` view. - Each `RouterView` looks up its own name in the matched record's `components` map. - The spelling matters: `components` with an **s** holds the map; `component` holds a single component for the default view. ## Named views versus nested routes | | Named views | Nested routes | |---|---|---| | Declared with | `components: { default, detail }` | `children: [...]` | | Layout | siblings side by side | one view inside another | | Records matched | one record fills several views | one record per level | | RouterViews | several at the same depth, different names | one per depth | | URL | one path for all panes | parent path plus child path | The two combine. A mail layout can be a parent route whose component holds named `RouterView`s, and its children can each declare `components` for those names. The docs' settings example does this: a child renders `default` and `helper` views inside the parent's component. ## When a view has no component If the matched record has no entry for a `RouterView`'s name, that view renders **nothing**. With the slot API, the slot still runs, with `Component` undefined. This is useful: - A route `/mail/:folder` can declare only `default`, leaving the detail pane empty until a message is chosen. - A route `/mail/:folder/:messageId` declares both. - A wide layout can show an extra `aside` view only on routes that define one. A typo in the name renders nothing too, without an error, so it is worth a test. ## What remounts in the mail client With one record `/mail/:folder/:messageId?` declaring both views: 1. Choosing another message changes only `messageId`. Both views keep the same components, so both instances are **reused**; each must watch its params. 2. Switching folders also reuses both; the list reloads by watching `folder`. With separate records, `/mail/:folder` declaring `default` only and `/mail/:folder/:messageId` declaring both, opening the first message mounts `MessageDetail` while the list component is reused, because the default view renders the same component under both records. ## Named views in nested layouts - The named `RouterView` must live at the depth where the record that declares the name renders. A `detail` view declared by a child record needs a `<RouterView name="detail" />` inside the parent's component, not in `App.vue`. - Per-view props need a map: `props: { default: true, detail: true }`. A bare `true` applies to every view. - A route that declares a component for a view name that no `RouterView` renders simply never shows it. ## One URL drives every pane Because all named views come from one matched route, the URL is the single source of truth for the whole screen: - A deep link to `/mail/inbox/42` reproduces both the list and the open message. - The browser's back button after opening a message returns to `/mail/inbox`, whose record declares no `detail` view, so the pane closes by itself. - Links and programmatic navigation only ever change the URL; no pane is shown or hidden by hand. - On narrow screens the layout can hide one of the `RouterView`s with CSS or a condition, while the route table stays the same. ## When to choose which - Choose **named views** when panes are peers that change together with one URL: list and detail, main and sidebar, content and contextual help. - Choose **nested routes** when one pane owns the others and should persist while they change: a settings layout around its sections. - Mixing them is normal; the depth-and-name rule tells you which `RouterView` renders what.
- The detail pane stays blank even on /mail/inbox/42. What would you check first?That the `RouterView name="detail"` sits at the depth where the record declaring `detail` renders: inside `MailLayout` for a child record, not in `App.vue`. Then check the spelling on both sides and that the record uses `components`, not `component`. A name mismatch renders nothing without an error.
- Why would you not implement the detail pane as a nested child of the list route?Nesting makes the detail render inside the list component's own `RouterView`, which couples the detail to the list's markup and layout. Named views keep the panes as peers in the layout, which fits side-by-side panes that are laid out by the parent and change together.
A newspaper page template with labelled boxes: headline, main story, sidebar. Each day's edition (the matched route) says what goes in each labelled box; a box the edition leaves out stays blank, and nobody builds a second page inside the first.
saying these in an interview costs you the question
- Named views are declared with a component option holding an object.
- A RouterView without a name renders every named component.
- A missing named component throws an error at navigation.
- Named views and nested routes cannot be combined.
- A named RouterView in App.vue can render a child record's named view.