Shaun Li hace 2 años
padre
commit
c1c9709ef4
Se han modificado 1 ficheros con 126 adiciones y 1 borrados
  1. 126 1
      README.md

+ 126 - 1
README.md

@@ -30,7 +30,7 @@ yarn add @shaun/alpinejs-router
 <a x-link href="/somewhere">Load template</a>
 
 <template x-route="/hello/:name">
-  <div>Say hello to <span x-text="$store.router.params.name"></span></div>
+  <div>Say hello to <span x-text="$router.params.name"></span></div>
 </template>
 
 <template x-route="/somewhere" template="/somewhere.html"></template>
@@ -45,3 +45,128 @@ somewhere.html
   <div x-show="open">Content...</div>
 </div>
 ```
+
+## Dynamic Route Matching with Params
+
+Very often we will need to map routes with the given pattern to the same template.
+For example we may have a `user` template which should be rendered for all users but with different user IDs.
+In `@shaun/alpinejs-router` we can use a dynamic segment in the path to achieve that, we call that a param:
+
+```html
+<!-- dynamic segments start with a colon -->
+<template x-route="/users/:id" template="/user.html"></template>
+```
+
+Now URLs like `/users/johnny` and `/users/jolyne` will both map to the same route.
+
+A param is denoted by a colon `:`. When a route is matched, the value of its params will be exposed as `$router.params`.
+Therefore, we can render the current user ID by updating user's template to this:
+
+```html
+<div>User ID: {$router.params.id}</div>
+```
+
+You can have multiple params in the same route, and they will map to corresponding fields on `$router.params`. Examples:
+
+| pattern | matched path | $router.params |
+| --- | --- | --- |
+| /users/:username | /users/eduardo | `{ username: 'eduardo' }` |
+| /users/:username/posts/:postId | /users/eduardo/posts/123 | `{ username: 'eduardo', postId: '123' }` |
+
+In addition to `$router.params`, the `$router` magic also exposes other useful information such as `$route.query` (if there is a query in the URL), `$router.path`, etc.
+
+## Routes' Matching Syntax
+
+Most applications will use static routes like `/about` and dynamic routes like `/users/:userId` like we just saw in Dynamic Route Matching, but `@shaun/alpinejs-router` has much more to offer!
+
+### Custom regex in params
+
+When defining a param like `:userId`, we internally use the following regex `([^/]+)` (at least one character that isn't a slash `/`) to extract params from URLs.
+This works well unless you need to differentiate two routes based on the param content. Imagine two routes `/:orderId` and `/:productName`, both would match the exact same URLs, so we need a way to differentiate them.
+The easiest way would be to add a static section to the path that differentiates them:
+
+```html
+<!-- matches /o/3549 -->
+<template x-route="/o/:orderId"></template>
+<!-- matches /p/books -->
+<template x-route="/p/:productName"></template>
+```
+
+But in some scenarios we don't want to add that static section `/o/p`. However, `orderId` is always a number while `productName` can be anything, so we can specify a custom regex for a param in parentheses:
+
+```html
+<!-- /:orderId -> matches only numbers -->
+<template x-route="/:orderId(\d+)"></template>
+<!-- /:productName -> matches anything else -->
+<template x-route="/:productName"></template>
+```
+
+Now, going to `/25` will match `/:orderId` while going to anything else will match `/:productName`. The order of the `routes` array doesn't even matter!
+
+## Programmatic Navigation
+
+Aside from using `<a x-link href="...">` to create anchor tags for declarative navigation, we can do this programmatically using the router's instance methods.
+
+### Navigate to a different location
+
+To navigate to a different URL, use `$router.push`. This method pushes a new entry into the history stack, so when the user clicks the browser back button they will be taken to the previous URL.
+
+This is the method called internally when you click a `x-link`, so clicking `<a x-link href="...">` is the equivalent of calling `$router.push(...)`.
+
+| Declarative | Programmatic |
+| --- | --- |
+| `<a x-link href="...">` | `$router.push(...)` |
+
+### Replace current location
+
+It acts like `$router.push`, the only difference is that it navigates without pushing a new history entry, as its name suggests - it replaces the current entry.
+
+| Declarative | Programmatic |
+| --- | --- |
+| `<a x-link.replace href="...">` | `$router.replace('...')` |
+
+### History Manipulation
+
+You may have noticed that `$router.push` and `$router.replace` are counterparts of `window.history.pushState` and `window.history.replaceState`, and they do imitate the `window.history` APIs.
+
+Therefore, if you are already familiar with [Browser History APIs](https://developer.mozilla.org/en-US/docs/Web/API/History_API), manipulating history will feel familiar when using `@shaun/alpinejs-router`.
+
+It is worth mentioning that `@shaun/alpinejs-router` navigation methods (push, replace) work consistently no matter the kind of `mode` option is passed when configuring the router instance.
+
+## Different History modes
+
+The `mode` option when configuring the router instance allows us to choose among different history modes.
+
+### Hash Mode
+
+The hash history mode is configured with `'hash'`:
+
+```html
+<body x-data x-init="$router.config({ mode: 'hash' })"></body>
+```
+
+It uses a hash character (`#`) before the actual URL that is internally passed.
+Because this section of the URL is never sent to the server, it doesn't require any special treatment on the server level.
+It does however have a bad impact in SEO. If that's a concern for you, use the HTML5 history mode.
+
+### HTML5 Mode
+
+The HTML5 mode is configured with `'web'` and is the recommended mode:
+
+```html
+<body x-data x-init="$router.config({ mode: 'web' })"></body>
+<!-- Or do nothing by default -->
+<body x-data></body>
+```
+
+When using `'web'`, the URL will look "normal," e.g. `https://example.com/user/id`. Beautiful!
+
+Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration,
+the users will get a 404 error if they access `https://example.com/user/id` directly in their browser. Now that's ugly.
+
+Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server.
+If the URL doesn't match any static assets, it should serve the same `index.html` page that your app lives in. Beautiful, again!
+
+## License
+
+Licensed under [MIT](https://github.com/shaunlee/alpinejs-router/blob/master/LICENSE)