diff --git a/docs/LANGS.md b/docs/LANGS.md index 6509bb8b9..6654d54e8 100644 --- a/docs/LANGS.md +++ b/docs/LANGS.md @@ -4,4 +4,5 @@ * [2.0 - German](de/) * [2.0 - Русский](ru/) * [2.0 - 한국어(Korean)](kr/) +* [2.0 - Español](es/) * [0.7 Docs](old/) diff --git a/docs/es/README.md b/docs/es/README.md new file mode 100644 index 000000000..f8a898044 --- /dev/null +++ b/docs/es/README.md @@ -0,0 +1 @@ +{% include "./SUMMARY.md" %} diff --git a/docs/es/SUMMARY.md b/docs/es/SUMMARY.md new file mode 100644 index 000000000..3f0c393f1 --- /dev/null +++ b/docs/es/SUMMARY.md @@ -0,0 +1,31 @@ +# vue-router 2 + +> Notas: vue-router@2.x funciona solamente con Vue 2.x. La documentación para la versión 0.7.x está [aquí (en inglés)](https://github.com/vuejs/vue-router/tree/1.0/docs/en). + +**[Notas de lanzamiento](https://github.com/vuejs/vue-router/releases)** + +- [Instalación](installation.md) +- Esenciales + - [Primeros pasos](essentials/getting-started.md) + - [Matching dinámico de rutas](essentials/dynamic-matching.md) + - [Sub-rutas](essentials/nested-routes.md) + - [Navegación mediante código](essentials/navigation.md) + - [Rutas con nombre](essentials/named-routes.md) + - [Vistas con nombre](essentials/named-views.md) + - [Redireccionamiento y alias](essentials/redirect-and-alias.md) + - [Pasando propiedades a componentes de ruteo](essentials/passing-props.md) + - [Modo historial HTML5](essentials/history-mode.md) +- Avanzado + - [Guardias de navegación](advanced/navigation-guards.md) + - [Campos Meta en las rutas](advanced/meta.md) + - [Transiciones](advanced/transitions.md) + - [Obtención de datos](advanced/data-fetching.md) + - [Comportamiento del scroll](advanced/scroll-behavior.md) + - [Lazy loading](advanced/lazy-loading.md) +- API + - [router-link](api/router-link.md) + - [router-view](api/router-view.md) + - [El objeto Route](api/route-object.md) + - [Opciones del constructor de Router](api/options.md) + - [La instancia de Router](api/router-instance.md) + - [Inyección en componentes](api/component-injections.md) diff --git a/docs/es/advanced/data-fetching.md b/docs/es/advanced/data-fetching.md new file mode 100644 index 000000000..e8dae4a87 --- /dev/null +++ b/docs/es/advanced/data-fetching.md @@ -0,0 +1,113 @@ +# Obtención de datos + +A veces es necesario obtener datos del servidor cuando una ruta es activada. Por ejemplo, antes de renderizar un perfil de usuario, puedes obtener la información de ese usuario desde el servidor. Podemos lograr esto de dos maneras diferentes: + +- **Obtener la información después de la navegación**: realiza la navegación primero y luego obtén los datos en un _hook_ del ciclo de vida del componente entrante. Puedes mostrar un indicador de carga mientras se obtienen los datos. + +- **Obtener la información antes de la navegación**: Obtén los datos antes de la navegación en la guardia de entrada de la ruta, y realiza la navegación una vez estos obtenidos. + +Técnicamente, ambas opciones son válidas - todo depende de la experiencia de usuario a la que apuntes. + +## Obtener la información después de la navegación + +Cuando utilizamos este enfoque, navegamos y renderizamos el componente entrante inmediatamente, y obtenemos los datos en el _hook_ `created` del componente. Esto nos permite mostrar un indicador de estado de carga mientras se obtiene la información desde un servidor remoto, y también manejar la carga de datos según la ruta. + +Asumamos que tenemos un componente `Post` que necesita obtener datos de un _post_ basándose en `$route.params.id`: + +``` html + +``` + +``` js +export default { + data () { + return { + loading: false, + post: null, + error: null + } + }, + created () { + // obtén los datos cuando la vista es creada y _data_ ya + // está siendo observada + this.fetchData() + }, + watch: { + // ejecuta nuevamente el método si la ruta cambia + '$route': 'fetchData' + }, + methods: { + fetchData () { + this.error = this.post = null + this.loading = true + // reemplaza getPost con lo que corresponda + getPost(this.$route.params.id, (err, post) => { + this.loading = false + if (err) { + this.error = err.toString() + } else { + this.post = post + } + }) + } + } +} +``` + +## Obtener la información antes de la navegación + +Con este enfoque, obtenemos la información antes de navegar a la nueva ruta. Podemos obtener los datos en el guardia `beforeRouteEnter` del componente entrante, y solo ejecutar `next` cuando se haya completado: + +``` js +export default { + data () { + return { + post: null, + error: null + } + }, + beforeRouteEnter (to, from, next) { + getPost(to.params.id, (err, post) => { + if (err) { + // muestra algún mensaje global de error + next(false) + } else { + next(vm => { + vm.post = post + }) + } + }) + }, + // cuando la ruta cambie y este componente ya haya sido renderizado, + // la lógica será ligeramente diferente + watch: { + $route () { + this.post = null + getPost(this.$route.params.id, (err, post) => { + if (err) { + this.error = err.toString() + } else { + this.post = post + } + }) + } + } +} +``` + +El usuario permanecerá en la vista actual mientras se esté obteniendo el recurso para la vista entrante. Por lo tanto, es recomendable mostrar algún tipo de indicador o barra de progreso. Si la obtención de datos falla, es necesario mostrar algún tipo de advertencia global. diff --git a/docs/es/advanced/lazy-loading.md b/docs/es/advanced/lazy-loading.md new file mode 100644 index 000000000..667518a61 --- /dev/null +++ b/docs/es/advanced/lazy-loading.md @@ -0,0 +1,44 @@ +# Lazy loading + +Cuando se construyen aplicaciones con un sistema de empaquetamiento de módulos, el archivo JavaScript resultante puede terminar siendo muy grande, afectando los tiempos de carga de la página. Sería más eficiente si pudiesemos dividir los componentes de cada ruta en porciones separadas y cargarlas solo cuando esa ruta es visitada. + +Combinando [las características asíncronas de componentes de Vue](http://vuejs.org/guide/components.html#Async-Components) y las características de división de código de [Webpack](https://webpack.js.org/guides/code-splitting-require/), es trivial el _lazy loading_ de componentes de ruta. + +Todo lo que necesitamos es definir nuestros componentes de rutas como asíncronos: + +``` js +const Foo = resolve => { + // require.ensure es la sintaxis especial de Webpack para indicar un punto de división de código. + require.ensure(['./Foo.vue'], () => { + resolve(require('./Foo.vue')) + }) +} +``` + +Hay una alternativa a la sintaxis de división de código utilizando _require_ como lo hace AMD, por lo que puede simplificarse como: + +``` js +const Foo = resolve => require(['./Foo.vue'], resolve) +``` + +Nada debe cambiarse en la configuración del _router_, solo utiliza `Foo` como lo harías normalmente: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/foo', component: Foo } + ] +}) +``` + +### Agrupando componentes en la misma porción + +A veces deseamos agrupar todos los componentes bajo la misma ruta en la misma porción asíncrona. Para lograr esto, necesitamos usar [porciones con nombre](https://webpack.js.org/guides/code-splitting-require/#chunkname) proveyendo un nombre de porción a `require.ensure` como el tercer argumento: + +``` js +const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo') +const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo') +const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo') +``` + +Webpack agrupará los módulos asíncronos con el mismo nombre dentro de la misma porción asíncrona - esto también significa que no necesitamos más listar explícitamente las dependencias de `require.ensure` (por lo tanto pasamos un array vacío). \ No newline at end of file diff --git a/docs/es/advanced/meta.md b/docs/es/advanced/meta.md new file mode 100644 index 000000000..feed2f7d1 --- /dev/null +++ b/docs/es/advanced/meta.md @@ -0,0 +1,51 @@ +# Campos Meta en las rutas + +Puedes incluir un campo `meta` cuando definas una ruta: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/foo', + component: Foo, + children: [ + { + path: 'bar', + component: Bar, + // campo meta + meta: { requiresAuth: true } + } + ] + } + ] +}) +``` + +Entonces, ¿como accedemos al campo `meta`? + +Primero, cada objeto route en la configuración de `routes` se llama **registro de ruta**. Los registros de ruta pueden estar anidados. Por lo tanto, cuando una ruta coincida, existe la posibilidad que lo haga con más de un registro de ruta. + +Por ejemplo, con la configuración anterior, la URL `/foo/bar` coincidirá tanto con el registro de ruta padre como con el hijo. + +Todos los registros de rutas que hayan coincidido son expuestos en el objeto `$route` (y también a los objetos route en las guardias de navegación) como el array `$route.matched`. Por ende, necesitaremos iterar sobre `$route.matched` para verificar campos meta en los registros de rutas. + +Un caso de uso de ejemplo es verificar la existencia de campos metas en los guardias de navegación global: + +``` js +router.beforeEach((to, from, next) => { + if (to.matched.some(record => record.meta.requiresAuth)) { + // esta ruta requiere autenticación, verificamos que haya iniciado sesión + // sino, redirigimos a la página de inicio de sesión. + if (!auth.loggedIn()) { + next({ + path: '/login', + query: { redirect: to.fullPath } + }) + } else { + next() + } + } else { + next() // ¡Asegúrate de ejecutar next siempre! + } +}) +``` diff --git a/docs/es/advanced/navigation-guards.md b/docs/es/advanced/navigation-guards.md new file mode 100644 index 000000000..8c079a752 --- /dev/null +++ b/docs/es/advanced/navigation-guards.md @@ -0,0 +1,109 @@ +# Guardias de navegación + +Como el nombre sugiere, las guardias de navegación provistas por `vue-router` son básicamente utilizadas para proteger rutas de navegación ya sea redireccionando o cancelándolas. Hay varias maneras de engancharse en el proceso de navegación de rutas: globalmente, por ruta o dentro de los componentes. + +Recuerda: **Los cambios en los parámetros o las _queries_ no harán que se ejecuten los guardias de navegación**. Simplemente [observa el objeto `$route`](../essentials/dynamic-matching.md#reacting-to-params-changes) para poder reaccionar frente a esos cambios. + +### Guardias globales + +Puedes registrar guardias _before_ globales utilizando `router.beforeEach`: + +``` js +const router = new VueRouter({ ... }) + +router.beforeEach((to, from, next) => { + // ... +}) +``` + +Las guardias _before_ globales son llamadas por orden de creación, cuando una navegación comienza. Las guardias pueden ejecutarse asincrónicamente, y la navegación se considera **pendiente** hasta que todos los _hooks_ sean resueltos. + +Cada función guardia recibe tres argumentos: + +- **`to: Route`**: el [Objeto Route](../api/route-object.md) hacia donde se navega. + +- **`from: Route`**: la ruta actual desde la cual se navega. + +- **`next: Function`**: esta función debe ser ejecutada para **resolver** el _hook_. La acción a realizar depende de los argumentos provistos a `next`: + + - **`next()`**: moverse al siguiente _hook_ en la cadena. Si no queda ninguno, la navegación se **confirma**. + + - **`next(false)`**: cancelar la navegación actual. Si la URL en el navegador cambió (ya sea manualmente o a través del botón _atrás_), será reseteada al valor de la ruta `from`. + + - **`next('/')` o `next({ path: '/' })`**: redirecciona a una ruta diferente. La navegación actual será abortada y una nueva será iniciada. + +**Asegúrese de llamar siempre a la función `next`, sino el _hook_ nunca será resuelto.** + +También puedes registrar _hooks after_ globales. Sin embargo, a diferencia de las guardias, estos _hooks_ no reciben una función `next` y no pueden afectar la navegación: + +``` js +router.afterEach((to, from) => { + // ... +}) +``` + +### Guardias por ruta + +Puedes definir guardias `beforeEnter` directamente en el objeto de configuración de una ruta: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/foo', + component: Foo, + beforeEnter: (to, from, next) => { + // ... + } + } + ] +}) +``` + +Estos guardias tienen exactamente la misma firma que los guardias _before_ globales. + +### Guardias en componentes + +Por último, puedes directamente definir guardias de navegación dentro de los componentes de ruta (los que son pasados a la configuración del `router`) con las siguientes opciones: + +- `beforeRouteEnter` +- `beforeRouteUpdate` (agregado en la versión 2.2) +- `beforeRouteLeave` + +``` js +const Foo = { + template: `...`, + beforeRouteEnter (to, from, next) { + // se llama antes que la ruta que renderiza este componente sea confirmada. + // NO tiene acceso a la instancia del componente `this`, + // ¡porque no ha sido creada todavía cuando este guardia es ejecutado! + }, + beforeRouteUpdate (to, from, next) { + // se llama cuando la ruta que renderiza este componente ha cambiado, + // pero este componente es reusado en la nueva ruta. + // Por ejemplo, para una ruta con parámetros dinámicos /foo/:id, cuando + // navegamos desde /foo/1 havia /foo/2, la misma instancia del componente Foo + // será reusada, y este _hook_ será llamado cuando eso suceda. + // Tiene acceso a la instancia del componente `this` + }, + beforeRouteLeave (to, from, next) { + // se llama cuando la ruta que renderiza el componente está por ser + // abandonada. + // Tiene acceso a la instancia del componente `this` + } +} +``` + +La guardia `beforeRouteEnter` **NO** tiene acceso a `this`, porque es ejecutada antes que la navegación sea confirmada, por lo tanto el componente destino todavía no ha sido creado. + +Sin embargo, puedes acceder a la instancia pasando una _función callback_ a `next`. La _función callback_ se ejecutará cuando la navegación sea confirmada, y la instancia del componente será pasada como argumento: + +``` js +beforeRouteEnter (to, from, next) { + next(vm => { + // accede a la instancia del componente a través de `vm` + }) +} +``` + +Puedes acceder directamente a `this` dentro de `beforeRouteLeave`. La guardia _leave_ se utiliza normalmente para prevenir al usuario cuando intenta abandonar la ruta accidentalmente sin guardar cambios. La navegación puede ser cancelada ejecutando `next(false)`. diff --git a/docs/es/advanced/scroll-behavior.md b/docs/es/advanced/scroll-behavior.md new file mode 100644 index 000000000..88024d197 --- /dev/null +++ b/docs/es/advanced/scroll-behavior.md @@ -0,0 +1,61 @@ +# Comportamiento del scroll + +Cuando se utiliza enrutamiento del lado cliente, podemos querer hacer `scroll` hacia el inicio de la página cuando naveguemos a una nueva ruta, o preservar la posición actual, tal cual lo hace una recarga de la página. `vue-router` te permite lograr esto e incluso más: permite personalizar completamente el comportamiento del `scroll` durante la navegación. + +**Nota: esta característica solo funciona en el modo historial de HTML5.** + +Cuando crees una instancia del `router`, puedes incluir la función `scrollBehavior`: + +``` js +const router = new VueRouter({ + routes: [...], + scrollBehavior (to, from, savedPosition) { + // devolver la posición deseada + } +}) +``` + +La función `scrollBehavior` recibe los objetos de ruta `to` y `from`. El tercer parámetro, `savedPosition`, solo está disponible si estamos en una navegación `popstate` (cuando se utilizan los botones _atrás_ o _adelante_ en el navegador). + +La función puede devolver un objeto de posición de `scroll`. El objeto puede ser de la forma: + +- `{ x: number, y: number }` +- `{ selector: string }` + +Si se devuelve un valor *falso* o un objeto vacio, no ocurrirá ningún desplazamiento. + +Por ejemplo: + +``` js +scrollBehavior (to, from, savedPosition) { + return { x: 0, y: 0 } +} +``` + +Esto hará que la página se desplace hacia el inicio para todas las navegaciones a la ruta. + +Devolver `savedPosition` hará que el comportamiento cuando se utilicen los botones _atrás_ o _adelante_ sea el nativo: + +``` js +scrollBehavior (to, from, savedPosition) { + if (savedPosition) { + return savedPosition + } else { + return { x: 0, y: 0 } + } +} +``` + +Si deseas simular el `scroll` hacia anclas: + +``` js +scrollBehavior (to, from, savedPosition) { + if (to.hash) { + return { + selector: to.hash + } + } +} +``` + +También podemos utilizar [campos meta](meta.md) para implementar un control de `scroll` fino. Un ejemplo completo [aquí](https://github.com/vuejs/vue-router/blob/dev/examples/scroll-behavior/app.js). diff --git a/docs/es/advanced/transitions.md b/docs/es/advanced/transitions.md new file mode 100644 index 000000000..17af3ff45 --- /dev/null +++ b/docs/es/advanced/transitions.md @@ -0,0 +1,58 @@ +# Transiciones + +Dado que `` es esencialmente un componente dinámico, podemos aplicarle efectos de transición utilizando el componente ``: + +``` html + + + +``` + +[Todo acerca de ``](http://vuejs.org/guide/transitions.html) también funciona aquí. + +### Transiciones por ruta + +El ejemplo anterior aplicará la misma transición a todas las rutas. Si deseas que cada componente de ruta tenga diferentes transiciones, puedes utilizar `` con diferentes nombres dentro de cada componente de ruta: + +``` js +const Foo = { + template: ` + +
...
+
+ ` +} + +const Bar = { + template: ` + +
...
+
+ ` +} +``` + +### Transiciones dinámicas basadas en componentes + +También es posible determinar dinámicamente la transición a utilizar basado en las relaciones entre la ruta destino y la ruta actual: + +``` html + + + + +``` + +``` js +// luego, en el componente padre, +// observa $route para determinar que transición utilizar +watch: { + '$route' (to, from) { + const toDepth = to.path.split('/').length + const fromDepth = from.path.split('/').length + this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' + } +} +``` + +Tienes un ejemplo completo [aquí](https://github.com/vuejs/vue-router/blob/dev/examples/transitions/app.js). diff --git a/docs/es/api/component-injections.md b/docs/es/api/component-injections.md new file mode 100644 index 000000000..d7dab556f --- /dev/null +++ b/docs/es/api/component-injections.md @@ -0,0 +1,20 @@ +# Inyección en componentes + +### Propiedades inyectadas + +Estas propiedades son inyectadas dentro de cada componente hijo pasando la instancia del `router` a la instancia principal como la opción `router`. + +- #### $router + + La instancia del `router`. + +- #### $route + + El objeto [Route activo](route-object.md). Esta propiedad es de solo lectura y sus propiedades son inmutables, pero puede ser observada. + +### Opciones habilitadas + +- **beforeRouteEnter** +- **beforeRouteLeave** + + Más información en [guardias en componentes](../advanced/navigation-guards.md#incomponent-guards). diff --git a/docs/es/api/options.md b/docs/es/api/options.md new file mode 100644 index 000000000..6d9fe2817 --- /dev/null +++ b/docs/es/api/options.md @@ -0,0 +1,70 @@ +# Opciones del constructor de Router + +### routes + +- tipo: `Array` + + Declaración de tipos para `RouteConfig`: + + ``` js + declare type RouteConfig = { + path: string; + component?: Component; + name?: string; // para rutas con nombre + components?: { [name: string]: Component }; // para vistas con nombre + redirect?: string | Location | Function; + props?: boolean | string | Function; + alias?: string | Array; + children?: Array; // para sub-rutas + beforeEnter?: (to: Route, from: Route, next: Function) => void; + meta?: any; + } + ``` + +### mode + +- tipo: `string` + +- valor por defecto: `"hash" (en navegadores) | "abstract" (en Node.js)` + +- valores disponibles: `"hash" | "history" | "abstract"` + + Configura el modo del `router`. + + - `hash`: utiliza el _hash_ en la URL para el enrutamiento. Funciona en todos los navegadores que soportan Vue, incluidos aquellos que no soportan la API de historial de HTML5 . + + - `history`: requiere la API de historial de HTML y configuración del lado servidor. [Modo historial HTML5](../essentials/history-mode.md). + + - `abstract`: funciona en todos los ambientes de JavaScript, por ejemplo, del lado servidor con Node.js. **Se forzará este modo de trabajo en el router si no se detecta la API de navegador.** + +### base + +- tipo: `string` + +- valor por defecto: `"/"` + + La URL base para la aplicación. Por ejemplo, si toda la aplicación se encuentra dentro de `/app/`, entonces `base` debería llevar ese valor. + +### linkActiveClass + +- tipo: `string` + +- valor por defecto: `"router-link-active"` + + Configura globalmente la clase activa por defecto de ``. Más información en [router-link](router-link.md). + +### scrollBehavior + +- tipo: `Function` + + Firma: + + ``` + ( + to: Route, + from: Route, + savedPosition?: { x: number, y: number } + ) => { x: number, y: number } | { selector: string } | ?{} + ``` + + Para más detalles, [comportamiento del scroll](../advanced/scroll-behavior.md). diff --git a/docs/es/api/route-object.md b/docs/es/api/route-object.md new file mode 100644 index 000000000..4aaae4fc0 --- /dev/null +++ b/docs/es/api/route-object.md @@ -0,0 +1,89 @@ +# El objeto Route + +Un **objeto Route** representa el estado de la ruta activa actualmente. Contiene información analizada de la URL actual y los **registros de rutas** que coinciden con ella. + +El objeto `Route` es inmutable. Cada navegación exitosa resultará en un nuevo objeto `Route`. + +El objeto `Route` puede encontrarse en diferentes lugares. + +- Dentro de los componentes, como `this.$route` + +- Dentro de las _funciones callbacks_ de observación de `$route` + +- Como valor de retorno de la función `router.match(location)` + +- Dentro de las guardias de navegación como los primeros dos argumentos: + + ``` js + router.beforeEach((to, from, next) => { + // to y from son objetos de ruta + }) + ``` + +- Dentro de la función `scrollBehavior`como los primeros dos argumentos: + + ``` js + const router = new VueRouter({ + scrollBehavior (to, from, savedPosition) { + // to y from son objetos de ruta + } + }) + ``` + +### Propiedades del objeto Route + +- **$route.path** + + - tipo: `string` + + Una cadena de texto equivalente a la ruta actual, siempre resuelta como una ruta absoluta. Por ejemplo`"/foo/bar"`. + +- **$route.params** + + - tipo: `Object` + + Un objeto que contiene pares llave/valor de segmentos dinámicos y segmentos estrella. Si no hay parametros, el valor será un objeto vacio. + +- **$route.query** + + - tipo: `Object` + + Un objeto que contiene pares llave/valor del _query string_. Por ejemplo, para la ruta `/foo?user=1`, obtendremos `$route.query.user == 1`. Si no hay _query string_ el valor será un objeto vacio. + +- **$route.hash** + + - tipo: `string` + + El _hash_ de la ruta actual (con la `#`), si posee. Si no hay un _hash_ el valor será una cadena de texto vacia. + +- **$route.fullPath** + + - tipo: `string` + + La URL completa incluyendo _query_ y _hash_. + +- **$route.matched** + + - tipo: `Array` + + Un array que contiene **registros de ruta** para todos los segmentos anidados de la ruta actual. Los registros de ruta son copias de los objetos en el array de configuración `routes` (y en los arrays `children`): + + ``` js + const router = new VueRouter({ + routes: [ + // el siguiente objeto es un registro de ruta + { path: '/foo', component: Foo, + children: [ + // este también es un registro de ruta + { path: 'bar', component: Bar } + ] + } + ] + }) + ``` + + Cuando la URL es `/foo/bar`, `$route.matched` será un array que contendrá ambos objetos (clonados), en orden descendente de padre a hijo. + +- **$route.name** + + El nombre de la ruta acutal, si tiene. (Más información en [rutas con nombre](../essentials/named-routes.md)) diff --git a/docs/es/api/router-instance.md b/docs/es/api/router-instance.md new file mode 100644 index 000000000..382aa472c --- /dev/null +++ b/docs/es/api/router-instance.md @@ -0,0 +1,69 @@ +# La instancia de Router + +### Propiedades + +#### router.app + +- tipo: `Vue instance` + + La instancia principal de Vue donde `router` fue inyectado. + +#### router.mode + +- tipo: `string` + + El [modo](options.md#mode) que `router` está utilizando. + +#### router.currentRoute + +- tipo: `Route` + + La ruta actual representada como un [objeto Route](route-object.md). + +### Métodos + +- **router.beforeEach(guard)** +- **router.afterEach(hook)** + + Agrega guardias de navegación globales. Info: [guardias de navegación](../advanced/navigation-guards.md). + + +- **router.push(location, onComplete?, onAbort?)** +- **router.replace(location, onComplete?, onAbort?)** +- **router.go(n)** +- **router.back()** +- **router.forward()** + + Navega mediante código a una nueva URL. Info: [navegación mediante código](../essentials/navigation.md). + +- **router.getMatchedComponents(location?)** + + Devuelve un array de componentes (definiciones/constructores, no instancias) que coincidan con la ubicación provista o la ruta actual. Se utiliza principalmente durante el renderizado del lado servidor para realizar precarga de datos. + +- **router.resolve(location, current?, append?)** + + > 2.1.0+ + + Resolución inversa de URL. Dada una ubicación de la misma forma que las usadas en ``, devuelve un objeto con las siguiente propiedades: + + ``` js + { + location: Location; + route: Route; + href: string; + } + ``` + +- **router.addRoutes(routes)** + + > 2.2.0+ + + Agrega dinámicamente más rutas al `router`. El argumento debe ser un array utilizando el mismo formato de configuración que las opciones del constructor de `routes`. + +- **router.onReady(callback)** + + > 2.2.0+ + + Este método pone una _función callback_ en espera a ser llamada cuando el `router` haya completado la navegación inicial, lo cual significa que ya ha resuelto todos los _hooks_ de entrada asíncronos y los componentes asíncronos asociados con la ruta inicial. + + Esto es útil en el renderizado del lado servidor para asegurar un resultado consistente tanto en el servidor como en el cliente. diff --git a/docs/es/api/router-link.md b/docs/es/api/router-link.md new file mode 100644 index 000000000..b7eed152c --- /dev/null +++ b/docs/es/api/router-link.md @@ -0,0 +1,128 @@ +# `` + +`` es el componente para posibilitar la navegación de los usuarios en una aplicación con el `router` habilitado. La ubicación destino se especifica con la propiedad `to`. Por defecto, renderiza una etiqueta `` con el atributo `href` correspondiente, pero puede configurarse mediante la propiedad `tag`. Además, el enlace obtiene una clase CSS cuando la ruta a la que apunta es activada. + +Es preferible utilizar `` en lugar de escribir directamente `` por las siguientes razones: + +- Funciona de la misma manera tanto en el modo _hash_ como en el modo historial de HTML5, por lo que si decides intercambiar modos, o cuando el `router` utiliza el modo _hash_ en IE9, no deberás modificar nada. + +- En el modo historial de HTML5, `router-link` interceptará el evento _click_ para que el navegador no intente recargar la página. + +- Cuando estés utilizando la opción `base` en el modo historial de HTML5, no necesitas incluirla en la URL de la propiedad `to`. + +### Propiedades + +- **to** + + - tipo: `string | Location` + + - requerida + + Identifica la ruta destino del enlace. Cuando es accedida, el valor de la propiedad `to` será pasado a `router.push()` internamente, por lo que el valor puede ser tanto una cadena de texto como un objeto descriptor de ubicación. + + ``` html + + Home + + Home + + + Home + + + Home + + + Home + + + User + + + Register + ``` + +- **replace** + + - tipo: `boolean` + + - valor por defecto: `false` + + Establecer la propiedad `replace` ejecutará `router.replace()` en lugar de `router.push()` cuando se acceda, por lo que la navegación no dejará un registro en el historial. + + ``` html + + ``` + +- **append** + + - tipo: `boolean` + + - valor por defecto: `false` + + Establecer la propiedad `append` hará que se agregue la ruta relativa a la ruta actual. Por ejemplo, asumiendo que estamos navegando desde `/a` a un enlace relativo `b`, sin `append` accederemos a `/b`, pero con `append` accederemos a `/a/b`. + + ``` html + + ``` + +- **tag** + + - tipo: `string` + + - valor por defecto: `"a"` + + A veces puede que quieras que `` se renderice como otra etiqueta, por ejemplo `
  • `. Puedes utilizar la propiedad `tag` para especificar que etiqueta renderizar, y seguirá escuchando eventos _click_ para la navegación. + + ``` html + foo + +
  • foo
  • + ``` + +- **active-class** + + - tipo: `string` + + - valor por defecto: `"router-link-active"` + + Configura la clase CSS que se aplicará al enlace cuando este activo. Nota que el valor por defecto puede ser configurado de manera global a través de la opción `linkActiveClass` del constructor del `router`. + +- **exact** + + - tipo: `boolean` + + - valor por defecto: `false` + + El comportamiento por defecto para la aplicación de la clase CSS activa en matching dinámico de rutas es **inclusivo**. Por ejemplo, `` obtendrá la clase CSS mientras la ruta actual comience con `/a/` o sea `/a`. + + Una consecuencia de esto es que `` ¡permanecerá activa para todas las rutas! Para forzar un matching exacto, utiliza la propiedad `exact`: + + ``` html + + + ``` + + Más ejemplos explicando la clase activa [aquí](https://jsfiddle.net/8xrk1n9f/). + +- **event** + + > 2.1.0+ + + - tipo: `string | Array` + + - valor por defecto: `'click'` + + Son los eventos que permiten lanzar la navegacion. + +### Aplicar la clase activa al elemento envolvente. + +A veces puede que queramos que la clase activa se aplique al elemento envolvente en lugar de aplicarla directamente a la etiqueta ``. En ese caso, puedes renderizar el elemento envolvente utilizando `` y luego una etiqueta `` dentro: + +``` html + + /foo + +``` + +En este caso, la etiqueta `` será el enlace (y obtendrá el atributo `href` correcto), pero la clase activa será aplicada al elemento envolvente `
  • `. diff --git a/docs/es/api/router-view.md b/docs/es/api/router-view.md new file mode 100644 index 000000000..fb5b63ecd --- /dev/null +++ b/docs/es/api/router-view.md @@ -0,0 +1,27 @@ +# `` + +El componente `` es un componente funcional que renderiza a otro en base a la ruta seleccionada. Los componentes renderizados en `` pueden contener su propio ``, el cual renderizará componentes para sub-rutas. + +### Propiedades + +- **name** + + - tipo: `string` + + - valor por defecto: `"default"` + + Cuando un componente `` tiene un nombre, renderizará el componente con el nombre correspondiente en la opción `components` del registro de ruta que coincida. Accede a [vistas con nombre](../essentials/named-views.md) para más información. + +### Comportamiento + +Cualquier propiedad diferente a `name` será pasada al componente renderizado. De cualquier manera, la mayor parte del tiempo los datos de la ruta están contenidos dentro de los parámetros de la ruta. + +Dado que es simplemente un componente, funciona con `` y ``. Cuando utilices ambos en conjunto, asegúrate de usar `` dentro de ``: + +``` html + + + + + +``` diff --git a/docs/es/essentials/dynamic-matching.md b/docs/es/essentials/dynamic-matching.md new file mode 100644 index 000000000..4c8934294 --- /dev/null +++ b/docs/es/essentials/dynamic-matching.md @@ -0,0 +1,74 @@ +# Matching dinámico de rutas + +Es bastante común tener que mapear rutas con un patrón determinado al mismo componente. Por ejemplo, puede que tengamos un componente `User` el cual debería ser renderizado para todos los usuarios, pero con diferente ID. En `vue-router` podemos usar un segmento dinámico en el _path_ para lograrlo: + +``` js +const User = { + template: '
    User
    ' +} + +const router = new VueRouter({ + routes: [ + // los segmentos dinámicos comienzan con dos puntos + { path: '/user/:id', component: User } + ] +}) +``` + +Ahora, las URL como `/user/foo` y `/user/bar` mapearán a la misma ruta. + +Un segmento dinámico se representa mediante dos puntos `:`. Cuando se encuentra una coincidencia en la ruta, el valor del segmento dinámico se expondrá como `this.$route.params` en cada componente. Por lo tanto, podremos renderizar el ID del usuario actual modificando el template de `User`de la siguiente manera: + +``` js +const User = { + template: '
    User {{ $route.params.id }}
    ' +} +``` + +Puedes consultar el siguiente [ejemplo](http://jsfiddle.net/yyx990803/4xfa2f19/). + +Se pueden tener múltiples segmentos dinámicos en la misma ruta, y todos serán mapeados a los correspondientes campos en `$route.params`. Por ejemplo: + +| patrón | matching de ruta | $route.params | +|---------|------|--------| +| /user/:username | /user/evan | `{ username: 'evan' }` | +| /user/:username/post/:post_id | /user/evan/post/123 | `{ username: 'evan', post_id: 123 }` | + +Además de `$route.params`, el objeto `$route` expone más información útil, como `$route.query` (si hay alguna _query_ en la URL), `$route.hash`, etc. Puedes verificar todos los detalles en la documentación de la [API](../api/route-object.md). + +### Reaccionando ante cambios de los parámetros + +Una cosa a tener en cuenta cuando se usan rutas con parámetros es que cuando el usuario navega de `/user/foo` a `/user/bar`, **la misma instancia del componente será reutilizada**. Dado que ambas rutas renderizan el mismo componente, esto es más eficiente que destruir la instancia anterior y crear una nueva. **Sin embargo, esto significa que los hooks del ciclo de vida del componentes no serán emitidos**. + +Para detectar cambios en los parámetros en el mismo componente, puedes observar el objeto `$route`: + +``` js +const User = { + template: '...', + watch: { + '$route' (to, from) { + // Código que responde al cambio + } + } +} +``` + +O utiliza el guardia de navegación `beforeRouteUpdate` introducido en la versión 2.2: + +``` js +const User = { + template: '...', + beforeRouteUpdate (to, from, next) { + // Código que responde al cambio + // no olvides ejecutar next() + } +} +``` + +### Patrones de matching avanzados + +`vue-router` usa [path-to-regexp](https://github.com/pillarjs/path-to-regexp) como su motor de búsqueda de patrones, por lo que soporta varios patrones de matching avanzados tales como segmentos dinámicos opcionales, requerimientos del tipo cero o más / uno o más, e incluso patrones _regex_ personalizados. Verifica la [documentación](https://github.com/pillarjs/path-to-regexp#parameters) para estos patrones avanzados, y [este ejemplo](https://github.com/vuejs/vue-router/blob/dev/examples/route-matching/app.js) de como usarlos con `vue-router`. + +### Prioridad en el matching de patrones + +A veces la misma URL puede coincidir con múltiples rutas. En ese caso, la prioridad se determina por el orden de la definición de las rutas: la primera ruta definida será la que tenga mayor prioridad. diff --git a/docs/es/essentials/getting-started.md b/docs/es/essentials/getting-started.md new file mode 100644 index 000000000..e146d44f4 --- /dev/null +++ b/docs/es/essentials/getting-started.md @@ -0,0 +1,68 @@ +# Primeros pasos + +> Utilizaremos [ES2015](https://github.com/lukehoban/es6features) en el código de los ejemplos en esta guía. + +Crear una aplicación de una sola página (SPA por sus siglas en inglés) con Vue.js + vue-router es muy sencillo. Con Vue.js, ya estamos estructurando nuestra aplicación con componentes. Cuando agregamos vue-router, todo lo que debemos hacer es mapear nuestros componentes a las rutas e informar a vue-router donde renderizarlas. Aquí hay un ejemplo básico: + +> Todos los ejemplos utilizarán la versión independiente de Vue para hacer posible el análisis de plantillas. Más detalles [aquí](https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only). + +### HTML + +``` html + + + +
    +

    Hello App!

    +

    + + + + Go to Foo + Go to Bar +

    + + +
    +``` + +### JavaScript + +``` js +// 0. Si utilizas un sistema de empaquetamiento de módulos (por ejemplo, a través de vue-cli), importa Vue y VueRouter y luego ejecuta Vue.use(VueRouter). + +// 1. Define componentes de enrutamiento. +// Estos pueden ser importados desde otros archivos +const Foo = { template: '
    foo
    ' } +const Bar = { template: '
    bar
    ' } + +// 2. Define algunas rutas +// Cada ruta debe mapear a un componente. El "componente" puede +// ser un constructor de componente creado a través de +// Vue.extend(), o simplemente un objeto de opciones de componente. +// Más tarde hablaremos acerca de las sub-rutas. +const routes = [ + { path: '/foo', component: Foo }, + { path: '/bar', component: Bar } +] + +// 3. Crea una instancia del _router_ y pasa la opción `routes` +// Puedes pasar opciones adicionales aquí, +// pero mantengámoslo simple por el momento. +const router = new VueRouter({ + routes // forma corta para routes: routes +}) + +// 4. Crea y monta la instancia principal. +// Asegúrate de inyectar el _router_ con la opcion router para +// garantizar que toda la aplicación tenga acceso al mismo. +const app = new Vue({ + router +}).$mount('#app') + +// ¡Ahora la aplicación está ejecutándose! +``` + +Puedes consultar este [ejemplo](http://jsfiddle.net/yyx990803/xgrjzsup/). + +Nota que `` obtiene automáticamente la clase `.router-link-active` cuando la ruta a la que apunta es accedida. Puedes leer más acerca de eso en la documentación de la [API](../api/router-link.md). diff --git a/docs/es/essentials/history-mode.md b/docs/es/essentials/history-mode.md new file mode 100644 index 000000000..f89b473ae --- /dev/null +++ b/docs/es/essentials/history-mode.md @@ -0,0 +1,60 @@ +# Modo historia HTML5 + +El modo por defecto para `vue-router` es _hash mode_ - el cual utiliza una almohadilla para simular la URL completa para que la página no sea recargada cuando la URL cambia. + +Para eliminar la almohadilla, podemos seleccionar el **modo historia** del `router`, el cual utiliza el método `history.pushState` de la API para conseguir una navegación sin recarga de página: + +``` js +const router = new VueRouter({ + mode: 'history', + routes: [...] +}) +``` + +Cuando utilices el modo historial, la URL lucirá "normal", por ejemplo: `http://oursite.com/user/id`. ¡Hermoso! + +Sin embargo, hay un problema: dado que nuestra aplicación es de una sola página del lado cliente, sin una configuración apropiada del lado servidor los usuarios van a obtener errores 404 si intentan acceder directamente a `http://oursite.com/user/id` en sus navegadores. Eso es horrible. + +No hay problema: para solucionar el error, todo lo que debes hacer es agregar un redireccionamiento en tu servidor. Si la URL no coincide con ningún recurso estático, debes apuntar a la misma página `index.html` donde se encuentra tu aplicación. De nuevo, ¡Hermoso! + +## Ejemplos de configuraciones de servidores + +#### Apache + +```apache + + RewriteEngine On + RewriteBase / + RewriteRule ^index\.html$ - [L] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . /index.html [L] + +``` + +#### nginx + +```nginx +location / { + try_files $uri $uri/ /index.html; +} +``` + +#### Node.js (Express) + +Para Node.js/Express, considera utilizar el middleware [connect-history-api-fallback](https://github.com/bripkens/connect-history-api-fallback). + +## Deventajas + +Hay una deventaja para esto: tu servidor ya no reportará errores 404 dado que todas las rutas no encontradas serán redireccionadas al archivo `index.html`. Para solucionar este problema debes implementar dentro de la aplicación Vue una ruta por defecto para mostrar una página de error 404: + +``` js +const router = new VueRouter({ + mode: 'history', + routes: [ + { path: '*', component: NotFoundComponent } + ] +}) +``` + +Otra solución, si utilizas un servidor Node.js, es utilizar el `router` del lado del servidor para analizar las URL ingresadas y responder con un error 404 si ninguna ruta coincide. diff --git a/docs/es/essentials/named-routes.md b/docs/es/essentials/named-routes.md new file mode 100644 index 000000000..222e953eb --- /dev/null +++ b/docs/es/essentials/named-routes.md @@ -0,0 +1,31 @@ +# Rutas con nombre + + A veces es conveniente identificar una ruta con un nombre, especialmente cuando enlazamos a esa ruta o navegamos mediante código. Puedes darle un nombre a una ruta en las opciones de `routes` cuando se crea la instancia de Router: + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/user/:userId', + name: 'user', + component: User + } + ] +}) +``` + +Para enlazar a una ruta con nombre, puedes pasar un objeto a la propiedad `to` del componente `router-link`: + +``` html +User +``` + +Este es exactamente el mismo objeto utilizado mediante código con `router.push()`: + +``` js +router.push({ name: 'user', params: { userId: 123 }}) +``` + +En ambos casos, el _router_ navegará a la ruta `/user/123`. + +Revisa un ejemplo completo [aquí](https://github.com/vuejs/vue-router/blob/dev/examples/named-routes/app.js). diff --git a/docs/es/essentials/named-views.md b/docs/es/essentials/named-views.md new file mode 100644 index 000000000..e82a34e1d --- /dev/null +++ b/docs/es/essentials/named-views.md @@ -0,0 +1,28 @@ +# Vistas con nombre + +A veces es necesario mostrar múltiples vistas al mismo tiempo en lugar de anidarlas. Por ejemplo, cuando se crea una plantilla con una vista `sidebar` y una vista `main`. Aquí es cuando las vistas con nombre se vuelven útiles. En lugar de tener un solo _outlet_ en tu vista, puedes tener varios y darle a cada uno un nombre diferente. Por defecto, un `router-view` sin nombre se llamará `default`. + +``` html + + + +``` + +Una vista se renderiza utilizando un componente, por lo tanto, múltiples vistas requerirán múltiples componentes para la misma ruta. Asegúrate de utilizar la opción `components` (con una _s_ al final): + +``` js +const router = new VueRouter({ + routes: [ + { + path: '/', + components: { + default: Foo, + a: Bar, + b: Baz + } + } + ] +}) +``` + +Puedes ver una demostración de este ejemplo [aquí](https://jsfiddle.net/posva/6du90epg/). diff --git a/docs/es/essentials/navigation.md b/docs/es/essentials/navigation.md new file mode 100644 index 000000000..cd6b3a96e --- /dev/null +++ b/docs/es/essentials/navigation.md @@ -0,0 +1,69 @@ +# Navegación mediante código + +Además de utilizar `` para crear etiquetas `a` para una navegación declarativa, podemos hacer lo mismo a través de código usando los métodos de la instancia del enrutador. + +#### `router.push(location, onComplete?, onAbort?)` + +Para navegar a una URL diferente, utiliza `router.push`. Este método agrega una nueva entrada a la pila del historial, por lo que cuando el usuario presione el botón _volver_ del navegador, será llevado a la URL anterior. + +Este método es el que se llama internamente cuando se hace clic en un componente ``, por lo que`` es el equivalente a ejecutar `router.push(...)`. + +| Declarativo | Mediante código | +|-------------|--------------| +| `` | `router.push(...)` | + +El argumento puede ser una cadena de texto o un objeto descriptor. Por ejemplo: + +``` js +// cadena de texto literal +router.push('home') + +// Objeto +router.push({ path: 'home' }) + +// Ruta con nombre +router.push({ name: 'user', params: { userId: 123 }}) + +// Con _query_, con lo que se obtiene /register?plan=private +router.push({ path: 'register', query: { plan: 'private' }}) +``` + +A partir de la version 2.2.0+, puedes opcionalmente pasar _funciones callbacks_ `onComplete` y `onAbort` a `router.push` o `router.replace` como segundo y tercer argumento. Estas _funciones callbacks_ serán ejecutadas cuando la navegación sea completada exitosamente (luego que todos los _hooks_ asíncronos sean resueltos), o abortada (navegando a la misma ruta, o a una ruta diferente antes que la navegación actual haya finalizado), respectivamente. + +#### `router.replace(location, onComplete?, onAbort?)` + +Actúa como `router.push`, la única diferencia es que navega sin agregar una nueva entrada al historial, como su nombre sugiere - reemplaza la entrada actual. + +| Declarativo | Mediante código | +|-------------|--------------| +| `` | `router.replace(...)` | + + +#### `router.go(n)` + +Este método toma un entero como parámetro que indica cuantos pasos avanzar o retroceder en el historial, similar a `window.history.go(n)`. + +Ejemplos + +``` js +// Ir hacia adelante un paso, similar a history.forward() +router.go(1) + +// Ir hacia atrás un paso, similar a history.back() +router.go(-1) + +// Ir 3 pasos hacia adelante +router.go(3) + +// Falla silenciosamente si no existe esa cantidad de registros en el historial +router.go(-100) +router.go(100) +``` + +#### Manipulación del historial + +Seguramente notaste que `router.push`, `router.replace` y `router.go` son contra partes de [`window.history.pushState`, `window.history.replaceState` y `window.history.go`](https://developer.mozilla.org/en-US/docs/Web/API/History), y que imitan a las API de `window.history`. + +Por lo tanto, si estás familiarizado con las [API del historial del navegador](https://developer.mozilla.org/en-US/docs/Web/API/History_API), manipularlo será muy sencillo con vue-router. + +Vale la pena mencionar que los métodos de navegacion de vue-router (`push`, `replace`, `go`) funcionan consistentemente en todos los modos de trabajo del `router` (`history`, `hash` y `abstract`). diff --git a/docs/es/essentials/nested-routes.md b/docs/es/essentials/nested-routes.md new file mode 100644 index 000000000..0a57ce116 --- /dev/null +++ b/docs/es/essentials/nested-routes.md @@ -0,0 +1,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 +
    + +
    +``` + +``` js +const User = { + template: '
    User {{ $route.params.id }}
    ' +} + +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User } + ] +}) +``` + +Aquí, `` 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 `` anidado. Por ejemplo, si agregamos uno dentro de la plantilla del componente `User`: + +``` js +const User = { + template: ` +
    +

    User {{ $route.params.id }}

    + +
    + ` +} +``` + +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 dentro de User + // cuando /user/:id/profile coincida + path: 'profile', + component: UserProfile + }, + { + // UserPosts será renderizado en el 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 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/). diff --git a/docs/es/essentials/passing-props.md b/docs/es/essentials/passing-props.md new file mode 100644 index 000000000..e33aedc14 --- /dev/null +++ b/docs/es/essentials/passing-props.md @@ -0,0 +1,72 @@ +# Pasando propiedades a componentes de ruteo + +Usar `$route` en tu componente genera un acoplamiento estrecho con la ruta, lo cual limita la flexibilidad del componente dado que solo puede utilizarse en ciertas URL. + +Para desacoplar el componente del enrutador utiliza _props_: + +**❌ Acoplado a $route** + +``` js +const User = { + template: '
    User {{ $route.params.id }}
    ' +} +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User } + ] +}) +``` + +**👍 Desacoplado con props** + +``` js +const User = { + props: ['id'], + template: '
    User {{ id }}
    ' +} +const router = new VueRouter({ + routes: [ + { path: '/user/:id', component: User, props: true } + ] +}) +``` + +Esto te permite utilizar el componente en cualquier lugar, lo cual hace al mismo reutilizable y más sencillo de testear. + +### Modo boolean + +Cuando _props_ tiene asignado el valor true, `route.params` serán asignados como las _props_ del componente. + +### Modo objeto + +Cuando _props_ es un objeto, este será asignado tal cual como las _props_ del componente. +Úitl para cuando las _props_ son estáticas. + +``` js +const router = new VueRouter({ + routes: [ + { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } + ] +}) +``` + +### Modo función + +Puedes crear una función que retorne _props_. +Esto te permite convertir los parámetros a otro tipo, combinar valores estáticos con valores basados en rutas, etc. + +``` js +const router = new VueRouter({ + routes: [ + { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) } + ] +}) +``` + +La URL: `/search?q=vue` pasaría `{query: "vue"}` como _props_ al componente SearchUser. + +Intenta crear funciones _props_ sin estado, dado que solo se evalúan cuando ocurren cambios de ruta. +Utiliza un componente envolvente si necesitas estado para definir las _props_, de esa manera Vue puede reaccionar a cambios de estado. + + +Para un uso avanzado, aquí hay un [ejemplo](https://github.com/vuejs/vue-router/blob/dev/examples/route-props/app.js). diff --git a/docs/es/essentials/redirect-and-alias.md b/docs/es/essentials/redirect-and-alias.md new file mode 100644 index 000000000..cce4a8c49 --- /dev/null +++ b/docs/es/essentials/redirect-and-alias.md @@ -0,0 +1,58 @@ +# Redireccionamiento y alias + +### Redireccionamiento + +El redireccionamiento también se realiza en la configuración de `routes`. Para redireccionar desde `/a` hasta `/b`: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', redirect: '/b' } + ] +}) +``` + +EL redireccionamiento también puede apuntar a una ruta con nombre: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', redirect: { name: 'foo' }} + ] +}) +``` + +O incluso puedes utilizar una función para un redireccionamiento dinámico: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', redirect: to => { + // la función recibe la ruta destino como argumento + // retorna aquí la ruta de redirección. + }} + ] +}) +``` + +Para otros usos avanzados, tienes el siguiente [ejemplo](https://github.com/vuejs/vue-router/blob/dev/examples/redirect/app.js). + +### Alias + +Una redirección significa que el usuario visita `/a`, y la URL será reemplazada por `/b`, para luego ejecutar el código correspondiente a `/b`. Pero, ¿qué es un alias? + +**Un alias de `/a` como `/b` significa que cuando el usuario visita `/b`, la URL se mantiene como `/b`, pero el código ejecutado corresponderá al mismo que si el usuario visitase `/a`.** + +Lo anterior puede ser expresado en la configuración de enrutamiento como: + +``` js +const router = new VueRouter({ + routes: [ + { path: '/a', component: A, alias: '/b' } + ] +}) +``` + +Un alias te da la libertad de mapear una estructura de _UI_ a una URL arbitraria, en lugar de estar restringido por la estructura anidada de la configuración. + +Para otros usos avanzados, aquí tienes un [ejemplo](https://github.com/vuejs/vue-router/blob/dev/examples/route-alias/app.js). diff --git a/docs/es/installation.md b/docs/es/installation.md new file mode 100644 index 000000000..36084d3d3 --- /dev/null +++ b/docs/es/installation.md @@ -0,0 +1,44 @@ +# Instalación + +### Descarga directa / CDN + +[https://unpkg.com/vue-router/dist/vue-router.js](https://unpkg.com/vue-router/dist/vue-router.js) + + +[Unpkg.com](https://unpkg.com) provee enlaces a CDN basadas en NPM. El enlace anterior siempre apuntará a la última versión en NPM. También puedes usar una versión/etiqueta específica a través de URLs como`https://unpkg.com/vue-router@2.0.0/dist/vue-router.js`. + + +Incluye `vue-router` luego de Vue y se instalará automáticamente: + +``` html + + +``` + +### NPM + +``` bash +npm install vue-router +``` + +Cuando lo utilices con un sistema de empaquetamiento de módulos, debes instalarlo explícitamente a través de `Vue.use()`: + +``` js +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) +``` + +No necesitas hacer esto cuando utilices etiquetas _script_ globales. + +### Versión de desarrollo + +Debes clonar el repositorio directamente desde GitHub y construir `vue-router` tu mismo si quieres utilizar la última versión de desarrollo. + +``` bash +git clone https://github.com/vuejs/vue-router.git node_modules/vue-router +cd node_modules/vue-router +npm install +npm run build +```