File: nested-routes.md

package info (click to toggle)
vue-router.js 3.4.9%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 3,212 kB
  • sloc: javascript: 7,982; sh: 22; makefile: 5
file content (99 lines) | stat: -rw-r--r-- 3,330 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Sub-rutas

Las interfaces de usuario (UI por sus siglas en inglés) de aplicaciones reales normalmente están compuestas por componentes que están anidados varios niveles. Es también muy común que los segmentos de una URL correspondan a cierta estructura de componentes anidados, por ejemplo:

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

Con `vue-router` es muy sencillo expresar esta relación usando configuraciones de sub-rutas.

Dada la aplicación que creamos en el capítulo anterior:

``` html
<div id="app">
  <router-view></router-view>
</div>
```

``` js
const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})
```

Aquí, `<router-view>` es un contenedor de nivel superior. Renderiza el componente que coincida con una ruta de nivel superior. Así, un componente renderizado puede contener su propio `<router-view>` anidado. Por ejemplo, si agregamos uno dentro de la plantilla del componente `User`:

``` js
const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}
```

Para renderizar componentes dentro de este contenedor anidado, necesitamos usar la opción `children` en la configuración del constructor de `VueRouter`:

``` js
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // UserProfile será renderizado en el <router-view> dentro de User
          // cuando /user/:id/profile coincida
          path: 'profile',
          component: UserProfile
        },
        {
          // UserPosts será renderizado en el <router-view> dentro de User
          // cuando /user/:id/posts coincida
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})
```

**Nota que las sub-rutas que empiecen con `/` serán tratadas como absolutas. Esto permite aprovechar el anidamiento de componentes sin tener que usar URL anidadas.**

Como puedes ver, la opción `children` es simplemente otro array de objetos de configuración de rutas, como `routes`. Por lo tanto, puedes anidar tantas vistas como necesites.

En este punto, con la configuración anterior, cuando visites `/user/foo`, nada será renderizado dentro del contenedor de  `User` porque ninguna sub ruta coincidió. Tal vez quieras renderizar algo ahí. En ese caso, puedes pasar una sub ruta vacía:

``` js
const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // UserHome será renderizado en el <router-view> dentro de User
        // cuando /user/:id coincida
        { path: '', component: UserHome },

        // ...otras sub rutas
      ]
    }
  ]
})
```

Puedes encontrar una demostración de este ejemplo [aquí](http://jsfiddle.net/yyx990803/L7hscd8h/).