Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
226 lines
4.4 KiB
Markdown
Executable File
226 lines
4.4 KiB
Markdown
Executable File
# @jqhtml/router
|
|
|
|
Client-side routing for JQHTML single-page applications.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @jqhtml/router @jqhtml/core jquery
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```javascript
|
|
import { Jqhtml_SPA, Jqhtml_Router, Jqhtml_Layout, Jqhtml_Route } from '@jqhtml/router';
|
|
import jqhtml from '@jqhtml/core';
|
|
|
|
// Define routes
|
|
const routes = [
|
|
{ path: '/', component: HomeRoute },
|
|
{ path: '/about', component: AboutRoute },
|
|
{ path: '/users/:id', component: UserRoute }
|
|
];
|
|
|
|
// Create SPA application
|
|
class MyApp extends Jqhtml_SPA {
|
|
constructor($element) {
|
|
super($element);
|
|
|
|
// Configure router
|
|
this.router = new Jqhtml_Router(routes, {
|
|
mode: 'hash', // or 'history'
|
|
base: '/'
|
|
});
|
|
}
|
|
}
|
|
|
|
// Initialize
|
|
$(document).ready(() => {
|
|
const app = new MyApp($('#app'));
|
|
app.start();
|
|
});
|
|
```
|
|
|
|
## Core Components
|
|
|
|
### Jqhtml_SPA
|
|
Base class for single-page applications. Manages the application lifecycle and router integration.
|
|
|
|
### Jqhtml_Router
|
|
Handles URL routing and navigation. Supports both hash (`#/route`) and history (`/route`) modes.
|
|
|
|
### Jqhtml_Layout
|
|
Persistent layout components that don't re-render on route changes.
|
|
|
|
### Jqhtml_Route
|
|
Base class for route components that render based on the current URL.
|
|
|
|
## Features
|
|
|
|
- **Hash & History Modes**: Support for both `#/path` and `/path` routing
|
|
- **Nested Routes**: Organize routes hierarchically
|
|
- **Route Parameters**: Extract values from URLs like `/users/:id`
|
|
- **Query Strings**: Parse and access URL query parameters
|
|
- **Layouts**: Persistent wrapper components across routes
|
|
- **Lazy Loading**: Load route components on demand
|
|
- **Navigation Guards**: Control route access with guards
|
|
- **Programmatic Navigation**: Navigate via JavaScript
|
|
|
|
## Route Configuration
|
|
|
|
```javascript
|
|
const routes = [
|
|
{
|
|
path: '/',
|
|
component: HomeRoute,
|
|
name: 'home'
|
|
},
|
|
{
|
|
path: '/users',
|
|
component: UsersLayout,
|
|
children: [
|
|
{ path: '', component: UsersList },
|
|
{ path: ':id', component: UserDetail },
|
|
{ path: ':id/edit', component: UserEdit }
|
|
]
|
|
},
|
|
{
|
|
path: '*',
|
|
component: NotFoundRoute
|
|
}
|
|
];
|
|
```
|
|
|
|
## Navigation
|
|
|
|
```javascript
|
|
// Programmatic navigation
|
|
router.navigate('/users/123');
|
|
router.navigate({ name: 'home' });
|
|
|
|
// With query parameters
|
|
router.navigate('/search', { query: { q: 'jqhtml' } });
|
|
|
|
// Replace instead of push
|
|
router.replace('/login');
|
|
|
|
// Go back/forward
|
|
router.back();
|
|
router.forward();
|
|
```
|
|
|
|
## Route Components
|
|
|
|
```javascript
|
|
class UserRoute extends Jqhtml_Route {
|
|
async load() {
|
|
// Access route parameters
|
|
const userId = this.params.id;
|
|
|
|
// Load data
|
|
this.data.user = await fetchUser(userId);
|
|
}
|
|
|
|
render() {
|
|
return `
|
|
<div class="user-detail">
|
|
<h1>${this.data.user.name}</h1>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Layouts
|
|
|
|
```javascript
|
|
class MainLayout extends Jqhtml_Layout {
|
|
render() {
|
|
return `
|
|
<div class="layout">
|
|
<header>
|
|
<nav>
|
|
<a href="#/">Home</a>
|
|
<a href="#/about">About</a>
|
|
</nav>
|
|
</header>
|
|
<main>
|
|
<div class="route-outlet"></div>
|
|
</main>
|
|
<footer>© 2024</footer>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
// Layouts don't re-render on route change
|
|
should_rerender() {
|
|
return false;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Navigation Guards
|
|
|
|
```javascript
|
|
router.beforeEach((to, from, next) => {
|
|
if (to.path.startsWith('/admin') && !isAuthenticated()) {
|
|
next('/login');
|
|
} else {
|
|
next();
|
|
}
|
|
});
|
|
|
|
router.afterEach((to, from) => {
|
|
// Update page title
|
|
document.title = to.meta.title || 'My App';
|
|
});
|
|
```
|
|
|
|
## URL Parameters
|
|
|
|
```javascript
|
|
// Route: /users/:id/posts/:postId
|
|
// URL: /users/123/posts/456?sort=date
|
|
|
|
class PostRoute extends Jqhtml_Route {
|
|
ready() {
|
|
console.log(this.params.id); // "123"
|
|
console.log(this.params.postId); // "456"
|
|
console.log(this.query.sort); // "date"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Hash Mode (Default)
|
|
|
|
Best for static file hosting and development:
|
|
|
|
```javascript
|
|
const router = new Jqhtml_Router(routes, {
|
|
mode: 'hash'
|
|
});
|
|
|
|
// URLs will be: file:///path/index.html#/route
|
|
// Or: https://example.com/#/route
|
|
```
|
|
|
|
## History Mode
|
|
|
|
For production servers with proper configuration:
|
|
|
|
```javascript
|
|
const router = new Jqhtml_Router(routes, {
|
|
mode: 'history',
|
|
base: '/app/'
|
|
});
|
|
|
|
// URLs will be: https://example.com/app/route
|
|
```
|
|
|
|
## API Reference
|
|
|
|
See [LLM_REFERENCE.md](./LLM_REFERENCE.md) for detailed API documentation.
|
|
|
|
## License
|
|
|
|
MIT |