@kalxjs/router
Version:
Advanced router package for KalxJs framework with features like lazy loading, route guards, and more.
739 lines (583 loc) • 14.4 kB
Markdown
# KalxJS Router API Reference
This document provides a comprehensive API reference for the KalxJS Router, which offers more powerful features.
## Table of Contents
- [Router Creation](#router-creation)
- [createRouter](#createrouter)
- [createWebHistory](#createwebhistory)
- [createWebHashHistory](#createwebhashhistory)
- [createMemoryHistory](#creatememoryhistory)
- [Router Instance](#router-instance)
- [router.push](#routerpush)
- [router.replace](#routerreplace)
- [router.go](#routergo)
- [router.back](#routerback)
- [router.forward](#routerforward)
- [router.beforeEach](#routerbeforeeach)
- [router.beforeResolve](#routerbeforeresolve)
- [router.afterEach](#routeraftereach)
- [router.addRoute](#routeraddroute)
- [router.removeRoute](#routerremoveroute)
- [router.hasRoute](#routerhasroute)
- [router.getRoutes](#routergetroutes)
- [router.install](#routerinstall)
- [Composition API](#composition-api)
- [useRouter](#userouter)
- [Components](#components)
- [RouterLink](#routerlink)
- [RouterView](#routerview)
- [Route Record](#route-record)
- [Location Format](#location-format)
- [Navigation Guards](#navigation-guards)
- [Meta Fields](#meta-fields)
- [TypeScript Support](#typescript-support)
## Router Creation
### createRouter
Creates a new router instance.
```javascript
import { createRouter } from '@kalxjs/router'
const router = createRouter({
// History implementation to use
history: createWebHistory(),
// Array of route records
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
],
// Optional configuration
scrollBehavior: (to, from, savedPosition) => {
// Return desired position
},
// Case sensitivity for routes
caseSensitive: false,
// Trailing slash handling
trailingSlash: false,
// Custom query parsing
parseQuery: (queryString) => {
// Return parsed query object
},
// Custom query stringifying
stringifyQuery: (queryObject) => {
// Return query string
}
})
```
### createWebHistory
Creates an HTML5 history implementation for `createRouter()`.
```javascript
import { createRouter, createWebHistory } from '@kalxjs/router'
const router = createRouter({
history: createWebHistory('/base/path/'),
routes: [...]
})
```
### createWebHashHistory
Creates a hash history implementation for `createRouter()`.
```javascript
import { createRouter, createWebHashHistory } from '@kalxjs/router'
const router = createRouter({
history: createWebHashHistory('/base/path/'),
routes: [...]
})
```
### createMemoryHistory
Creates a memory history implementation for `createRouter()`, useful for server-side rendering and testing.
```javascript
import { createRouter, createMemoryHistory } from '@kalxjs/router'
const router = createRouter({
history: createMemoryHistory('/initial/path'),
routes: [...]
})
```
## Router Instance
### router.push
Navigate to a new URL programmatically. Returns a Promise that resolves when navigation is complete.
```javascript
// Navigate to a path
router.push('/users/123')
// Navigate with an object
router.push({
path: '/users/123',
query: { plan: 'premium' }
})
// Navigate to a named route
router.push({
name: 'user',
params: { id: '123' },
query: { plan: 'premium' },
hash: '#bio'
})
// With promise handling
router.push('/users/123')
.then(route => {
console.log('Navigation complete:', route)
})
.catch(error => {
console.error('Navigation failed:', error)
})
```
### router.replace
Navigate to a new URL, replacing the current history entry. Returns a Promise that resolves when navigation is complete.
```javascript
// Replace current URL
router.replace('/users/123')
// Replace with an object
router.replace({
name: 'user',
params: { id: '123' }
})
// With promise handling
router.replace('/login')
.then(route => {
console.log('Navigation complete:', route)
})
.catch(error => {
console.error('Navigation failed:', error)
})
```
### router.go
Go forward or backward in history. Returns a Promise.
```javascript
// Go back one record
router.go(-1)
// Go forward one record
router.go(1)
// Go back 3 records
router.go(-3)
```
### router.back
Go back in history. Equivalent to `router.go(-1)`. Returns a Promise.
```javascript
router.back()
```
### router.forward
Go forward in history. Equivalent to `router.go(1)`. Returns a Promise.
```javascript
router.forward()
```
### router.beforeEach
Add a global navigation guard that runs before any route navigation. Returns an unregister function.
```javascript
const unregisterGuard = router.beforeEach((to, from, next) => {
// Check if route requires authentication
if (to.meta.requiresAuth && !isAuthenticated()) {
// Redirect to login
next({ path: '/login', query: { redirect: to.fullPath } })
} else {
// Continue navigation
next()
}
})
// Later, unregister the guard
unregisterGuard()
```
### router.beforeResolve
Add a global navigation guard that runs after all component-specific guards and async route components are resolved. Returns an unregister function.
```javascript
const unregisterGuard = router.beforeResolve(async (to, from, next) => {
try {
// Fetch data before navigation completes
await fetchDataForRoute(to)
next()
} catch (error) {
next(error) // Abort navigation with error
}
})
// Later, unregister the guard
unregisterGuard()
```
### router.afterEach
Add a global hook that runs after navigation is complete. Returns an unregister function.
```javascript
const unregisterHook = router.afterEach((to, from) => {
// Update page title
document.title = to.meta.title || 'KalxJS App'
// Track page view
analytics.trackPageView(to.fullPath)
})
// Later, unregister the hook
unregisterHook()
```
### router.addRoute
Dynamically add a new route to the router. If a `parentName` is provided, the route will be added as a child of that route.
```javascript
// Add a top-level route
router.addRoute({
path: '/dynamic',
name: 'dynamic-route',
component: DynamicComponent
})
// Add a child route
router.addRoute('parent-name', {
path: 'child', // Will be '/parent-path/child'
name: 'child-route',
component: ChildComponent
})
```
### router.removeRoute
Remove a route by name.
```javascript
router.removeRoute('route-name')
```
### router.hasRoute
Check if a route with the given name exists.
```javascript
const exists = router.hasRoute('route-name')
```
### router.getRoutes
Get a list of all route records.
```javascript
const routes = router.getRoutes()
```
### router.install
Install the router on a KalxJS application.
```javascript
import { createApp } from '@kalxjs/core'
import { createRouter } from '@kalxjs/router'
const app = createApp(App)
const router = createRouter({ /* options */ })
app.use(router)
// or
router.install(app)
```
## Composition API
### useRouter
Composition API hook to access the router and current route from any component.
```javascript
import { useRouter } from '@kalxjs/router'
export default {
setup() {
const {
// Router instance
router,
// Route state (reactive)
route,
params,
query,
path,
hash,
fullPath,
meta,
name,
matched,
// Navigation methods
push,
replace,
go,
back,
forward,
// Route matching helpers
isActive,
isExactActive,
// Route construction helpers
resolve,
// Navigation guards
beforeEach,
beforeResolve,
afterEach
} = useRouter()
// Examples of usage
// Navigate programmatically
const goToProfile = () => {
push('/profile')
}
// Check if a route is active
const isProfileActive = isActive('/profile')
// Resolve a route to get its URL
const { href } = resolve({ name: 'user', params: { id: 123 } })
return {
goToProfile,
isProfileActive,
// ...
}
}
}
```
## Components
### RouterLink
Component for navigation with automatic active class application.
```javascript
import { RouterLink } from '@kalxjs/router'
// Basic usage
<RouterLink to="/about">About</RouterLink>
// With named route
<RouterLink to={{ name: 'user', params: { id: 123 } }}>User Profile</RouterLink>
// With replace mode
<RouterLink to="/login" replace>Login</RouterLink>
// With custom active classes
<RouterLink
to="/products"
activeClass="my-active-class"
exactActiveClass="my-exact-active-class"
>
Products
</RouterLink>
// With custom tag
<RouterLink to="/contact" tag="button">Contact Us</RouterLink>
// With custom rendering
<RouterLink to="/dashboard" custom>
{({ href, navigate, isActive, isExactActive }) => (
<a
href={href}
onClick={navigate}
class={isExactActive ? 'exact-active' : isActive ? 'active' : ''}
>
Dashboard
</a>
)}
</RouterLink>
```
### RouterView
Component that displays the component for the current route.
```javascript
import { RouterView } from '@kalxjs/router'
// Basic usage
<RouterView />
// With named views
<RouterView name="sidebar" />
<RouterView name="main" />
// With scoped slot for transitions
<RouterView>
{({ Component, route }) => (
<Transition name={route.meta.transition || 'fade'}>
<Component />
</Transition>
)}
</RouterView>
```
## Route Record
A route record represents a route configuration.
```javascript
{
// Required
path: '/users/:id',
// One of the following is required
component: UserComponent,
components: {
default: UserComponent,
sidebar: UserSidebar
},
redirect: '/user/profile',
redirect: to => {
// Return route location
return { name: 'profile' }
},
// Optional
name: 'user',
alias: ['/u/:id', '/profile/:id'],
meta: {
requiresAuth: true,
title: 'User Profile'
},
props: true, // Pass route.params as component props
props: { default: true, sidebar: false },
props: route => ({ id: Number(route.params.id) }),
// Nested routes
children: [
{
path: 'profile',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
],
// Route-specific navigation guards
beforeEnter: (to, from, next) => {
// ...
next()
},
beforeEnter: [guardA, guardB]
}
```
## Location Format
A location can be specified in multiple formats:
```javascript
// String path
'/users/123'
// Object format
{
path: '/users/123',
query: { plan: 'premium' },
hash: '#bio'
}
// Named route with params
{
name: 'user',
params: { id: '123' }
}
// With query and hash
{
name: 'user',
params: { id: '123' },
query: { plan: 'premium' },
hash: '#bio'
}
// With replace flag
{
path: '/users/123',
replace: true
}
```
## Navigation Guards
Navigation guards are hooks that can be used to control navigation flow.
### Global Guards
```javascript
// Before each navigation
router.beforeEach((to, from, next) => {
// ...
next() // Continue
next(false) // Abort
next('/login') // Redirect
next({ name: 'login' }) // Redirect to named route
next(new Error()) // Abort with error
})
// After async components are resolved
router.beforeResolve((to, from, next) => {
// ...
next()
})
// After navigation is complete
router.afterEach((to, from) => {
// ...
})
```
### Per-Route Guards
```javascript
const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: (to, from, next) => {
// ...
next()
},
// Multiple guards
beforeEnter: [guardA, guardB]
}
]
```
### Component Guards
```javascript
const UserDetails = {
setup() {
// ...
},
// Called before the component is created
beforeRouteEnter(to, from, next) {
// Cannot access 'this' here
next(vm => {
// Access component instance via vm
})
},
// Called when route params change for the same component
beforeRouteUpdate(to, from, next) {
// Can access 'this'
next()
},
// Called when navigating away from this component
beforeRouteLeave(to, from, next) {
// Can access 'this'
next()
}
}
```
## Meta Fields
Route meta fields can be used to attach custom data to routes.
```javascript
const routes = [
{
path: '/admin',
component: Admin,
meta: {
requiresAuth: true,
roles: ['admin'],
title: 'Admin Dashboard',
transition: 'fade'
},
children: [
{
path: 'settings',
component: AdminSettings,
// Child routes inherit parent meta and can override or extend it
meta: {
roles: ['super-admin'],
title: 'Admin Settings'
}
}
]
}
]
// Accessing meta fields
router.beforeEach((to, from, next) => {
// Meta fields from all matched route records are merged
const requiresAuth = to.meta.requiresAuth
const roles = to.meta.roles
// ...
})
```
## TypeScript Support
KalxJS Router provides enhanced TypeScript support.
### Typing Route Params
```typescript
// Define param types
interface UserParams {
id: string
tab?: 'profile' | 'settings'
}
// Use in route definition
const routes: RouteDefinition<UserParams>[] = [
{
path: '/users/:id/:tab?',
name: 'user',
component: UserComponent
}
]
```
### Typing Meta Fields
```typescript
// Define meta types
interface RouteMeta {
requiresAuth: boolean
title: string
roles?: string[]
}
// Use in route definition
const routes: RouteDefinition<any, RouteMeta>[] = [
{
path: '/admin',
component: AdminComponent,
meta: {
requiresAuth: true,
title: 'Admin Dashboard',
roles: ['admin']
}
}
]
```
### Typing Both Params and Meta
```typescript
// Combined typing
const routes: RouteDefinition<UserParams, RouteMeta>[] = [
{
path: '/users/:id/:tab?',
name: 'user',
component: UserComponent,
meta: {
requiresAuth: true,
title: 'User Profile'
}
}
]
```
### Type-Safe Access in Components
```typescript
// In component
const { params, meta } = useRouter<UserParams, RouteMeta>()
// TypeScript knows:
// - params.value.id is a string
// - params.value.tab is an optional 'profile' | 'settings'
// - meta.value.requiresAuth is a boolean
// - meta.value.title is a string
// - meta.value.roles is an optional string array
```