lego-dom 0.0.5 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/deploy-docs.yml +56 -0
- package/LICENSE +21 -0
- package/README.md +298 -355
- package/docs/.vitepress/config.js +107 -0
- package/docs/.vitepress/dist/404.html +22 -0
- package/docs/.vitepress/dist/api/define.html +35 -0
- package/docs/.vitepress/dist/api/directives.html +32 -0
- package/docs/.vitepress/dist/api/globals.html +27 -0
- package/docs/.vitepress/dist/api/index.html +25 -0
- package/docs/.vitepress/dist/api/lifecycle.html +38 -0
- package/docs/.vitepress/dist/api/route.html +34 -0
- package/docs/.vitepress/dist/api/vite-plugin.html +37 -0
- package/docs/.vitepress/dist/assets/api_define.md.UA-ygUnQ.js +11 -0
- package/docs/.vitepress/dist/assets/api_define.md.UA-ygUnQ.lean.js +1 -0
- package/docs/.vitepress/dist/assets/api_directives.md.BV-D251p.js +8 -0
- package/docs/.vitepress/dist/assets/api_directives.md.BV-D251p.lean.js +1 -0
- package/docs/.vitepress/dist/assets/api_globals.md.DOjt7AV0.js +3 -0
- package/docs/.vitepress/dist/assets/api_globals.md.DOjt7AV0.lean.js +1 -0
- package/docs/.vitepress/dist/assets/api_index.md.OS6h01ct.js +1 -0
- package/docs/.vitepress/dist/assets/api_index.md.OS6h01ct.lean.js +1 -0
- package/docs/.vitepress/dist/assets/api_lifecycle.md.Ccm5xw6-.js +14 -0
- package/docs/.vitepress/dist/assets/api_lifecycle.md.Ccm5xw6-.lean.js +1 -0
- package/docs/.vitepress/dist/assets/api_route.md.CAHf_KNp.js +10 -0
- package/docs/.vitepress/dist/assets/api_route.md.CAHf_KNp.lean.js +1 -0
- package/docs/.vitepress/dist/assets/api_vite-plugin.md.DNn9VhL5.js +13 -0
- package/docs/.vitepress/dist/assets/api_vite-plugin.md.DNn9VhL5.lean.js +1 -0
- package/docs/.vitepress/dist/assets/app.BG5s3B0P.js +1 -0
- package/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.DQmuWC2Z.js +1 -0
- package/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.BO-PSxt1.js +9 -0
- package/docs/.vitepress/dist/assets/chunks/framework.B7OFBR9X.js +19 -0
- package/docs/.vitepress/dist/assets/chunks/theme.DA-iSa9B.js +2 -0
- package/docs/.vitepress/dist/assets/examples_form.md.B3stGKbu.js +34 -0
- package/docs/.vitepress/dist/assets/examples_form.md.B3stGKbu.lean.js +1 -0
- package/docs/.vitepress/dist/assets/examples_index.md.BDEG_D4J.js +30 -0
- package/docs/.vitepress/dist/assets/examples_index.md.BDEG_D4J.lean.js +1 -0
- package/docs/.vitepress/dist/assets/examples_routing.md.bqZ9DjDK.js +338 -0
- package/docs/.vitepress/dist/assets/examples_routing.md.bqZ9DjDK.lean.js +1 -0
- package/docs/.vitepress/dist/assets/examples_sfc-showcase.md.DLXaUiop.js +13 -0
- package/docs/.vitepress/dist/assets/examples_sfc-showcase.md.DLXaUiop.lean.js +1 -0
- package/docs/.vitepress/dist/assets/examples_todo-app.md.D5RhZoo5.js +297 -0
- package/docs/.vitepress/dist/assets/examples_todo-app.md.D5RhZoo5.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_cdn-usage.md.CAjf03Lr.js +182 -0
- package/docs/.vitepress/dist/assets/guide_cdn-usage.md.CAjf03Lr.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_components.md.BIFWF1Hc.js +174 -0
- package/docs/.vitepress/dist/assets/guide_components.md.BIFWF1Hc.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_contributing.md.BgbUN-Mr.js +1 -0
- package/docs/.vitepress/dist/assets/guide_contributing.md.BgbUN-Mr.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_directives.md.Bi3ynu1d.js +140 -0
- package/docs/.vitepress/dist/assets/guide_directives.md.Bi3ynu1d.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_getting-started.md.2Nr1lp2z.js +107 -0
- package/docs/.vitepress/dist/assets/guide_getting-started.md.2Nr1lp2z.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_index.md.GvZq_Yf2.js +2 -0
- package/docs/.vitepress/dist/assets/guide_index.md.GvZq_Yf2.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_lifecycle.md.B28j1OzS.js +304 -0
- package/docs/.vitepress/dist/assets/guide_lifecycle.md.B28j1OzS.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_quick-start.md.CNk3VGTF.js +33 -0
- package/docs/.vitepress/dist/assets/guide_quick-start.md.CNk3VGTF.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_reactivity.md.CVsaMaPv.js +135 -0
- package/docs/.vitepress/dist/assets/guide_reactivity.md.CVsaMaPv.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_routing.md.DSpDP25o.js +193 -0
- package/docs/.vitepress/dist/assets/guide_routing.md.DSpDP25o.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_sfc.md.CVUP66tS.js +187 -0
- package/docs/.vitepress/dist/assets/guide_sfc.md.CVUP66tS.lean.js +1 -0
- package/docs/.vitepress/dist/assets/guide_templating.md.BgCGe4aa.js +119 -0
- package/docs/.vitepress/dist/assets/guide_templating.md.BgCGe4aa.lean.js +1 -0
- package/docs/.vitepress/dist/assets/index.md.xV1taCED.js +23 -0
- package/docs/.vitepress/dist/assets/index.md.xV1taCED.lean.js +1 -0
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
- package/docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
- package/docs/.vitepress/dist/assets/style.eycE2Jhw.css +1 -0
- package/docs/.vitepress/dist/examples/form.html +58 -0
- package/docs/.vitepress/dist/examples/index.html +368 -0
- package/docs/.vitepress/dist/examples/routing.html +362 -0
- package/docs/.vitepress/dist/examples/sfc-showcase.html +37 -0
- package/docs/.vitepress/dist/examples/todo-app.html +321 -0
- package/docs/.vitepress/dist/guide/cdn-usage.html +206 -0
- package/docs/.vitepress/dist/guide/components.html +198 -0
- package/docs/.vitepress/dist/guide/contributing.html +25 -0
- package/docs/.vitepress/dist/guide/directives.html +164 -0
- package/docs/.vitepress/dist/guide/getting-started.html +131 -0
- package/docs/.vitepress/dist/guide/index.html +26 -0
- package/docs/.vitepress/dist/guide/lifecycle.html +328 -0
- package/docs/.vitepress/dist/guide/quick-start.html +57 -0
- package/docs/.vitepress/dist/guide/reactivity.html +159 -0
- package/docs/.vitepress/dist/guide/routing.html +217 -0
- package/docs/.vitepress/dist/guide/sfc.html +211 -0
- package/docs/.vitepress/dist/guide/templating.html +143 -0
- package/docs/.vitepress/dist/hashmap.json +1 -0
- package/docs/.vitepress/dist/index.html +47 -0
- package/docs/.vitepress/dist/logo.svg +38 -0
- package/docs/.vitepress/dist/vp-icons.css +1 -0
- package/docs/api/define.md +31 -0
- package/docs/api/directives.md +42 -0
- package/docs/api/globals.md +29 -0
- package/docs/api/index.md +29 -0
- package/docs/api/lifecycle.md +40 -0
- package/docs/api/route.md +37 -0
- package/docs/api/vite-plugin.md +58 -0
- package/docs/examples/form.md +42 -0
- package/docs/examples/index.md +104 -0
- package/docs/examples/routing.md +409 -0
- package/docs/examples/sfc-showcase.md +34 -0
- package/docs/examples/todo-app.md +383 -0
- package/docs/guide/cdn-usage.md +320 -0
- package/docs/guide/components.md +394 -0
- package/docs/guide/contributing.md +32 -0
- package/docs/guide/directives.md +430 -0
- package/docs/guide/getting-started.md +233 -0
- package/docs/guide/index.md +88 -0
- package/docs/guide/lifecycle.md +493 -0
- package/docs/guide/quick-start.md +46 -0
- package/docs/guide/reactivity.md +394 -0
- package/docs/guide/routing.md +373 -0
- package/docs/guide/sfc.md +381 -0
- package/docs/guide/templating.md +383 -0
- package/docs/index.md +126 -0
- package/docs/public/logo.svg +38 -0
- package/examples/vite-app/README.md +71 -0
- package/examples/vite-app/index.html +45 -0
- package/examples/vite-app/package.json +16 -0
- package/examples/vite-app/src/components/greeting-card.lego +41 -0
- package/examples/vite-app/src/components/sample-component.lego +75 -0
- package/examples/vite-app/src/main.js +11 -0
- package/examples/vite-app/vite.config.js +16 -0
- package/examples.js +99 -0
- package/package.json +34 -7
- package/parse-lego.js +119 -0
- package/parse-lego.test.js +107 -0
- package/vite-plugin.js +133 -0
- package/.ignore/auto.html +0 -135
- package/.ignore/test.html +0 -73
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# Routing
|
|
2
|
+
|
|
3
|
+
LegoJS includes a built-in client-side router for building single-page applications.
|
|
4
|
+
|
|
5
|
+
## Basic Setup
|
|
6
|
+
|
|
7
|
+
### 1. Add Router Outlet
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<lego-router></lego-router>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This is where your routed components will render.
|
|
14
|
+
|
|
15
|
+
### 2. Define Routes
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
Lego.route('/', 'home-page');
|
|
19
|
+
Lego.route('/about', 'about-page');
|
|
20
|
+
Lego.route('/contact', 'contact-page');
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 3. Create Page Components
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<template b-id="home-page">
|
|
27
|
+
<h1>Home</h1>
|
|
28
|
+
<p>Welcome to the homepage!</p>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<template b-id="about-page">
|
|
32
|
+
<h1>About</h1>
|
|
33
|
+
<p>Learn more about us.</p>
|
|
34
|
+
</template>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 4. Add Navigation
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<nav>
|
|
41
|
+
<a href="/" b-link>Home</a>
|
|
42
|
+
<a href="/about" b-link>About</a>
|
|
43
|
+
<a href="/contact" b-link>Contact</a>
|
|
44
|
+
</nav>
|
|
45
|
+
|
|
46
|
+
<lego-router></lego-router>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The `b-link` attribute hijacks clicks to prevent page reloads.
|
|
50
|
+
|
|
51
|
+
## Complete Example
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<!DOCTYPE html>
|
|
55
|
+
<html>
|
|
56
|
+
<head>
|
|
57
|
+
<title>My SPA</title>
|
|
58
|
+
<style>
|
|
59
|
+
nav { padding: 1rem; background: #f0f0f0; }
|
|
60
|
+
nav a { margin-right: 1rem; text-decoration: none; }
|
|
61
|
+
nav a.active { font-weight: bold; }
|
|
62
|
+
</style>
|
|
63
|
+
</head>
|
|
64
|
+
<body>
|
|
65
|
+
<nav>
|
|
66
|
+
<a href="/" b-link>Home</a>
|
|
67
|
+
<a href="/blog" b-link>Blog</a>
|
|
68
|
+
<a href="/about" b-link>About</a>
|
|
69
|
+
</nav>
|
|
70
|
+
|
|
71
|
+
<lego-router></lego-router>
|
|
72
|
+
|
|
73
|
+
<template b-id="home-page">
|
|
74
|
+
<h1>Welcome Home</h1>
|
|
75
|
+
<p>This is the homepage.</p>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<template b-id="blog-page">
|
|
79
|
+
<h1>Blog</h1>
|
|
80
|
+
<ul>
|
|
81
|
+
<li><a href="/blog/1" b-link>First Post</a></li>
|
|
82
|
+
<li><a href="/blog/2" b-link>Second Post</a></li>
|
|
83
|
+
</ul>
|
|
84
|
+
</template>
|
|
85
|
+
|
|
86
|
+
<template b-id="about-page">
|
|
87
|
+
<h1>About Us</h1>
|
|
88
|
+
<p>We build awesome things.</p>
|
|
89
|
+
</template>
|
|
90
|
+
|
|
91
|
+
<script src="https://unpkg.com/lego-dom/main.js"></script>
|
|
92
|
+
<script>
|
|
93
|
+
Lego.route('/', 'home-page');
|
|
94
|
+
Lego.route('/blog', 'blog-page');
|
|
95
|
+
Lego.route('/about', 'about-page');
|
|
96
|
+
</script>
|
|
97
|
+
</body>
|
|
98
|
+
</html>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Dynamic Routes
|
|
102
|
+
|
|
103
|
+
Use `:param` syntax for URL parameters:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
Lego.route('/user/:id', 'user-profile');
|
|
107
|
+
Lego.route('/blog/:slug', 'blog-post');
|
|
108
|
+
Lego.route('/category/:cat/item/:id', 'product-detail');
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Accessing Parameters
|
|
112
|
+
|
|
113
|
+
Route parameters are available in `global.params`:
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<template b-id="user-profile">
|
|
117
|
+
<h1>User Profile</h1>
|
|
118
|
+
<p>User ID: {{ global.params.id }}</p>
|
|
119
|
+
<button @click="loadUser()">Load User</button>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<script>
|
|
123
|
+
Lego.define('user-profile',
|
|
124
|
+
Lego.registry['user-profile'].innerHTML, {
|
|
125
|
+
async loadUser() {
|
|
126
|
+
const userId = Lego.globals.params.id;
|
|
127
|
+
const user = await fetch(`/api/users/${userId}`).then(r => r.json());
|
|
128
|
+
this.username = user.name;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
</script>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Programmatic Navigation
|
|
135
|
+
|
|
136
|
+
Navigate programmatically using the History API:
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
// Navigate to a new route
|
|
140
|
+
history.pushState({}, '', '/about');
|
|
141
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
142
|
+
|
|
143
|
+
// Or in a component method:
|
|
144
|
+
{
|
|
145
|
+
goToAbout() {
|
|
146
|
+
history.pushState({}, '', '/about');
|
|
147
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Route Middleware
|
|
153
|
+
|
|
154
|
+
Add middleware for authentication, logging, etc:
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
// Define middleware function
|
|
158
|
+
const authMiddleware = (params, globals) => {
|
|
159
|
+
if (!globals.isLoggedIn) {
|
|
160
|
+
history.pushState({}, '', '/login');
|
|
161
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
162
|
+
return false; // Block navigation
|
|
163
|
+
}
|
|
164
|
+
return true; // Allow navigation
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Apply to routes
|
|
168
|
+
Lego.route('/dashboard', 'dashboard-page', authMiddleware);
|
|
169
|
+
Lego.route('/profile', 'profile-page', authMiddleware);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Middleware Example
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
// Logging middleware
|
|
176
|
+
const logger = (params) => {
|
|
177
|
+
console.log('Navigating to:', params);
|
|
178
|
+
return true;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// Analytics middleware
|
|
182
|
+
const analytics = (params) => {
|
|
183
|
+
if (window.gtag) {
|
|
184
|
+
gtag('event', 'page_view', { page_path: window.location.pathname });
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// Apply
|
|
190
|
+
Lego.route('/products/:id', 'product-page', (params, globals) => {
|
|
191
|
+
logger(params);
|
|
192
|
+
analytics(params);
|
|
193
|
+
return true;
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Active Link Styling
|
|
198
|
+
|
|
199
|
+
Style active navigation links:
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
// Update active class on navigation
|
|
203
|
+
window.addEventListener('popstate', () => {
|
|
204
|
+
document.querySelectorAll('[b-link]').forEach(link => {
|
|
205
|
+
const isActive = link.getAttribute('href') === window.location.pathname;
|
|
206
|
+
link.classList.toggle('active', isActive);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## 404 / Not Found
|
|
212
|
+
|
|
213
|
+
Handle unknown routes:
|
|
214
|
+
|
|
215
|
+
```js
|
|
216
|
+
// Define all your routes
|
|
217
|
+
Lego.route('/', 'home-page');
|
|
218
|
+
Lego.route('/about', 'about-page');
|
|
219
|
+
|
|
220
|
+
// Catch-all for 404
|
|
221
|
+
const matchRoute = () => {
|
|
222
|
+
const path = window.location.pathname;
|
|
223
|
+
const routes = ['/', '/about']; // Your known routes
|
|
224
|
+
|
|
225
|
+
if (!routes.includes(path)) {
|
|
226
|
+
// Show 404
|
|
227
|
+
document.querySelector('lego-router').innerHTML = '<not-found></not-found>';
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
window.addEventListener('popstate', matchRoute);
|
|
232
|
+
matchRoute(); // Initial check
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Nested Routes
|
|
236
|
+
|
|
237
|
+
While LegoJS doesn't have built-in nested routing, you can implement it:
|
|
238
|
+
|
|
239
|
+
```html
|
|
240
|
+
<template b-id="blog-layout">
|
|
241
|
+
<aside>
|
|
242
|
+
<a href="/blog/posts" b-link>Posts</a>
|
|
243
|
+
<a href="/blog/authors" b-link>Authors</a>
|
|
244
|
+
</aside>
|
|
245
|
+
<main>
|
|
246
|
+
<blog-posts b-if="global.params.section === 'posts'"></blog-posts>
|
|
247
|
+
<blog-authors b-if="global.params.section === 'authors'"></blog-authors>
|
|
248
|
+
</main>
|
|
249
|
+
</template>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
Lego.route('/blog/:section', 'blog-layout');
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Query Strings
|
|
257
|
+
|
|
258
|
+
Access query parameters using URLSearchParams:
|
|
259
|
+
|
|
260
|
+
```js
|
|
261
|
+
{
|
|
262
|
+
mounted() {
|
|
263
|
+
const params = new URLSearchParams(window.location.search);
|
|
264
|
+
this.searchQuery = params.get('q') || '';
|
|
265
|
+
this.page = parseInt(params.get('page')) || 1;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Example: `/search?q=legojs&page=2`
|
|
271
|
+
|
|
272
|
+
## Hash vs History Mode
|
|
273
|
+
|
|
274
|
+
LegoJS uses History API (pushState) by default, giving you clean URLs:
|
|
275
|
+
|
|
276
|
+
✅ `/about`
|
|
277
|
+
✅ `/user/123`
|
|
278
|
+
✅ `/blog/my-post`
|
|
279
|
+
|
|
280
|
+
Not hash-based:
|
|
281
|
+
❌ `#/about`
|
|
282
|
+
❌ `#/user/123`
|
|
283
|
+
|
|
284
|
+
### Server Configuration
|
|
285
|
+
|
|
286
|
+
For clean URLs to work, configure your server to serve `index.html` for all routes:
|
|
287
|
+
|
|
288
|
+
**nginx:**
|
|
289
|
+
```nginx
|
|
290
|
+
location / {
|
|
291
|
+
try_files $uri $uri/ /index.html;
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Apache (.htaccess):**
|
|
296
|
+
```apache
|
|
297
|
+
RewriteEngine On
|
|
298
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
|
299
|
+
RewriteCond %{REQUEST_FILENAME} !-d
|
|
300
|
+
RewriteRule ^ index.html [L]
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Node.js/Express:**
|
|
304
|
+
```js
|
|
305
|
+
app.get('*', (req, res) => {
|
|
306
|
+
res.sendFile(path.join(__dirname, 'index.html'));
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Best Practices
|
|
311
|
+
|
|
312
|
+
### 1. Centralize Route Definitions
|
|
313
|
+
|
|
314
|
+
```js
|
|
315
|
+
// routes.js
|
|
316
|
+
const routes = {
|
|
317
|
+
'/': 'home-page',
|
|
318
|
+
'/blog': 'blog-page',
|
|
319
|
+
'/blog/:slug': 'blog-post',
|
|
320
|
+
'/user/:id': 'user-profile',
|
|
321
|
+
'/about': 'about-page'
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
Object.entries(routes).forEach(([path, component]) => {
|
|
325
|
+
Lego.route(path, component);
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 2. Loading States
|
|
330
|
+
|
|
331
|
+
```html
|
|
332
|
+
<template b-id="user-profile">
|
|
333
|
+
<div b-if="loading">Loading...</div>
|
|
334
|
+
<div b-if="!loading">
|
|
335
|
+
<h1>{{ user.name }}</h1>
|
|
336
|
+
<p>{{ user.bio }}</p>
|
|
337
|
+
</div>
|
|
338
|
+
</template>
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 3. Error Handling
|
|
342
|
+
|
|
343
|
+
```js
|
|
344
|
+
{
|
|
345
|
+
async loadData() {
|
|
346
|
+
this.loading = true;
|
|
347
|
+
this.error = null;
|
|
348
|
+
try {
|
|
349
|
+
const data = await fetch('/api/data').then(r => r.json());
|
|
350
|
+
this.data = data;
|
|
351
|
+
} catch (err) {
|
|
352
|
+
this.error = 'Failed to load data';
|
|
353
|
+
} finally {
|
|
354
|
+
this.loading = false;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Limitations
|
|
361
|
+
|
|
362
|
+
- No nested router outlets (single level only)
|
|
363
|
+
- No route guards (use middleware instead)
|
|
364
|
+
- No automatic scroll restoration
|
|
365
|
+
- Routes must be defined upfront (not lazy-loaded)
|
|
366
|
+
|
|
367
|
+
For complex routing needs, consider integrating a dedicated router library.
|
|
368
|
+
|
|
369
|
+
## Next Steps
|
|
370
|
+
|
|
371
|
+
- See [routing examples](/examples/routing)
|
|
372
|
+
- Learn about [lifecycle hooks](/guide/lifecycle)
|
|
373
|
+
- Explore [state management patterns](/guide/reactivity)
|