viewlogic
Version:
A lightweight, file-based routing system for Vue 3 applications with zero build configuration
938 lines (785 loc) β’ 33.5 kB
Markdown
# ViewLogic Router v1.1.1
<p align="center">
<a href="https://github.com/hopegiver/viewlogic">
<img src="https://img.shields.io/npm/v/viewlogic.svg" alt="npm version">
</a>
<a href="https://github.com/hopegiver/viewlogic/blob/main/LICENSE">
<img src="https://img.shields.io/npm/l/viewlogic.svg" alt="license">
</a>
<a href="https://github.com/hopegiver/viewlogic">
<img src="https://img.shields.io/npm/dm/viewlogic.svg" alt="downloads">
</a>
</p>
> A revolutionary Vue 3 routing system with View-Logic separation and Zero Build Development
## π Latest Updates (v1.1.1)
- β¨ **Automatic Form Handling** - Revolutionary form submission with `{paramName}` variable parameters
- π **Multiple API Support** - Parallel data fetching from multiple APIs with named data storage
- π‘οΈ **Enhanced Validation** - HTML5 + custom function validation with graceful error handling
- π **Component Loading Resilience** - Router continues to work even if components fail to load
- π **Comprehensive Documentation** - Extensive real-world examples and usage patterns
## π― Core Philosophy: Simplicity Through Design
ViewLogic Router revolutionizes Vue development with two fundamental core principles:
### π View-Logic Separation
**Complete separation between View (presentation) and Logic (business logic)**. Views are pure HTML templates, logic is pure JavaScript components, making your code more maintainable, testable, and scalable.
### π Zero Build Development
**Zero build step required in development mode**. Work directly with source files, see changes instantly without any compilation, bundling, or build processes. True real-time development experience.
## β¨ Key Features
- π **Ultra-Lightweight** - Complete routing system in just 13KB gzipped (48KB minified)
- π **Multiple API Support** - Parallel data fetching from multiple APIs with named data storage
- π **Automatic Form Handling** - Revolutionary form submission with `{paramName}` variable parameters
- π οΈ **Built-in Components** - Preloaded UI components including revolutionary DynamicInclude & HtmlInclude
- π **Query-Based Parameter System** - Simple query-only parameters (`/users?id=123`) instead of complex path parameters
- β‘ **Optimized Production** - Pre-built individual route bundles for lightning-fast production
- π **Intuitive Structure** - Organized folder structure for views, logic, styles, layouts, and components
- πΎ **Smart Caching** - Intelligent route and component caching
- π **Authentication** - Built-in auth management system
- π **i18n Ready** - Built-in internationalization support
## π¦ Installation
Create a new ViewLogic project with our complete template:
```bash
npm create viewlogic my-app
cd my-app
# Ready to go! No additional setup needed
```
Or manually install the router only:
```bash
npm install viewlogic
```
## π Quick Start
### Development Mode (No Build Required!)
```html
<html>
<head>
<meta charset="UTF-8">
<title>My ViewLogic App - Development</title>
<link rel="stylesheet" href="/css/base.css">
</head>
<body>
<div id="app"></div>
<!-- Vue 3 (development version) -->
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/viewlogic/dist/viewlogic-router.umd.js"></script>
<script>
// Development mode - loads files directly from src/
ViewLogicRouter({
environment: 'development',
});
</script>
</body>
</html>
```
### Production Mode (Optimized Bundles)
```html
<html>
<head>
<meta charset="UTF-8">
<title>My ViewLogic App</title>
<link rel="stylesheet" href="/css/base.css">
</head>
<body>
<div id="app"></div>
<!-- Vue 3 (production version) -->
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
<script src="https://cdn.jsdelivr.net/npm/viewlogic/dist/viewlogic-router.umd.js"></script>
<script>
// Production mode - loads pre-built bundles from routes/
ViewLogicRouter({
environment: 'production',
useI18n: true,
logLevel: 'error' // Only log errors
});
</script>
</body>
</html>
```
### ES6 Module Usage
```javascript
import { ViewLogicRouter } from 'js/viewlogic-router.js';
// Create router instance
const router = new ViewLogicRouter({
environment: 'development'
});
// Router will automatically initialize and handle routing
```
### CommonJS/Node.js Usage
```javascript
const { createRouter } = require('js/viewlogic-router.umd.js');
createRouter({
environment: 'development'
}).then(router => {
console.log('Router ready');
});
```
## π Project Structure
### Development Mode Structure
```
my-app/
βββ index.html
βββ i18n/ # Language files (top-level)
β βββ ko.json
β βββ en.json
βββ css/ # Global styles
β βββ base.css # Base styles for entire site
βββ js/ # System files (optional, can use CDN)
β βββ viewlogic-router.js
β βββ viewlogic-router.min.js
β βββ viewlogic-router.umd.js
βββ src/ # Source files (not deployed)
β βββ views/ # View templates (HTML)
β β βββ home.html
β β βββ about.html
β β βββ products/
β β βββ list.html
β β βββ detail.html
β βββ logic/ # Business logic (JavaScript)
β β βββ home.js
β β βββ about.js
β β βββ products/
β β βββ list.js
β β βββ detail.js
β βββ styles/ # Page-specific CSS
β β βββ home.css
β β βββ about.css
β β βββ products/
β β βββ list.css
β β βββ detail.css
β βββ layouts/ # Layout templates
β β βββ default.html
β β βββ admin.html
β βββ components/ # Reusable components
β βββ Button.js
β βββ Modal.js
β βββ Card.js
βββ package.json
```
### Production Deployment Structure
```
my-app/
βββ index.html
βββ i18n/ # Language files
β βββ ko.json
β βββ en.json
βββ css/ # Global styles
β βββ base.css
βββ js/ # Router system (or use CDN)
β βββ viewlogic-router.umd.js
β βββ viewlogic-router.min.js
βββ routes/ # Built & optimized route bundles
β βββ home.js # Combined view + logic + style
β βββ about.js
β βββ products/
β βββ list.js
β βββ detail.js
βββ assets/ # Static assets
βββ images/
βββ fonts/
Note: src/ folder is excluded from production deployment
```
## π§ Configuration Options
```javascript
const config = {
// Basic Configuration
basePath: '/src', // Base path for all resources
mode: 'hash', // 'hash' or 'history'
environment: 'development', // 'development' or 'production'
// Routing
routesPath: '/routes', // Routes directory path
defaultLayout: 'default', // Default layout name
useLayout: true, // Enable layouts
// Caching
cacheMode: 'memory', // 'memory' or 'session' or 'none'
cacheTTL: 300000, // Cache TTL in milliseconds
maxCacheSize: 50, // Maximum cache entries
// Components
useComponents: true, // Enable built-in components
componentNames: [ // Components to preload
'Button', 'Modal', 'Card', 'Toast',
'Input', 'Tabs', 'Checkbox', 'Alert'
],
// Internationalization
useI18n: true, // Enable i18n
defaultLanguage: 'ko', // Default language
// Authentication
authEnabled: false, // Enable authentication
loginRoute: 'login', // Login route name
protectedRoutes: [], // Protected route names
publicRoutes: ['login', 'register', 'home'],
authStorage: 'cookie', // 'cookie' or 'localStorage'
// Security
enableParameterValidation: true,
maxParameterLength: 1000,
maxParameterCount: 50,
// Development
logLevel: 'info', // 'debug', 'info', 'warn', 'error'
enableErrorReporting: true
};
```
### ποΈ Subfolder Deployment Support
ViewLogic Router supports deployment in subfolders with smart path resolution:
```javascript
// Root deployment: https://example.com/
ViewLogicRouter({
basePath: '/src', // β https://example.com/src
routesPath: '/routes', // β https://example.com/routes
i18nPath: '/i18n' // β https://example.com/i18n
});
// Subfolder deployment: https://example.com/myapp/
ViewLogicRouter({
basePath: 'src', // β https://example.com/myapp/src (relative)
routesPath: 'routes', // β https://example.com/myapp/routes (relative)
i18nPath: 'i18n', // β https://example.com/myapp/i18n (relative)
});
// Mixed paths: https://example.com/projects/myapp/
ViewLogicRouter({
basePath: './src', // β https://example.com/projects/myapp/src
routesPath: '../shared/routes', // β https://example.com/projects/shared/routes
i18nPath: '/global/i18n' // β https://example.com/global/i18n (absolute)
});
```
**Path Resolution Rules:**
- **Absolute paths** (`/path`) β `https://domain.com/path`
- **Relative paths** (`path`, `./path`) β Resolved from current page location
- **Parent paths** (`../path`) β Navigate up directory levels
- **HTTP URLs** β Used as-is (no processing)
### π Hash vs History Mode in Subfolders
Both routing modes work seamlessly in subfolder deployments:
```javascript
// Hash Mode (recommended for subfolders)
// URL: https://example.com/myapp/#/products?id=123
ViewLogicRouter({
mode: 'hash' // Works anywhere, no server config needed
});
// History Mode (requires server configuration)
// URL: https://example.com/myapp/products?id=123
ViewLogicRouter({
mode: 'history' // Cleaner URLs, needs server setup
});
```
**History Mode Server Configuration:**
```nginx
# Nginx - redirect all subfolder requests to index.html
location /myapp/ {
try_files $uri $uri/ /myapp/index.html;
}
```
```apache
# Apache .htaccess in /myapp/ folder
RewriteEngine On
RewriteBase /myapp/
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /myapp/index.html [L]
```
## π Complete API Documentation
For comprehensive API documentation including all methods, configuration options, and detailed examples, see:
**π [Complete API Reference β](./docs/index.md)**
### Quick API Overview
```javascript
// Basic router usage
const router = new ViewLogicRouter({ environment: 'development' });
router.navigateTo('products', { id: 123, category: 'electronics' });
const current = router.getCurrentRoute();
// In route components - global methods automatically available:
export default {
dataURL: '/api/products', // Auto-fetch data
mounted() {
const id = this.getParam('id'); // Get parameter
this.navigateTo('detail', { id }); // Navigate
console.log('Data loaded:', this.products); // From dataURL
if (this.$isAuthenticated()) { /* auth check */ }
const text = this.$t('welcome.message'); // i18n
}
};
```
### Key Global Methods (Auto-available in all route components)
- **Navigation**: `navigateTo()`, `getCurrentRoute()`
- **Parameters**: `getParams()`, `getParam(key, defaultValue)`
- **Data Fetching**: `$fetchData()`, `$fetchAllData()` (with dataURL)
- **Authentication**: `$isAuthenticated()`, `$getToken()`, `$logout()`
- **Forms**: Auto-binding with `action` attribute and `{param}` templates
- **i18n**: `$t(key, params)` for translations
### Auto-Injected Properties
```javascript
// Automatically available in every route component:
// currentRoute, $query, $lang, $dataLoading
```
## π― View-Logic Separation: Core Philosophy in Action
ViewLogic Router's fundamental philosophy of **View-Logic Separation** creates clear boundaries between concerns:
### Philosophy Benefits
- **π¨ Pure Presentation**: Views contain only HTML - no mixed logic or scripts
- **π§ Pure Logic**: JavaScript components focus solely on business logic
- **β‘ Zero Build Required**: Work directly with separate files in development
- **π Hot Reload**: Instant changes without compilation or bundling
### File Structure (Core Philosophy)
- **View**: `src/views/products.html` - Pure HTML template
- **Logic**: `src/logic/products.js` - Pure Vue component logic
- **Style**: `src/styles/products.css` - Pure CSS styles
### Example: Philosophy in Practice
```javascript
// src/logic/products.js - Pure business logic
export default {
name: 'ProductsList',
dataURL: '/api/products', // Auto-fetch data
data() {
return { title: 'Our Products' };
},
methods: {
viewDetail(id) {
this.navigateTo('product-detail', { id });
}
}
};
```
### Production: Automatic Optimization
All separate files automatically combine into optimized bundles in `routes/` folder - maintaining the development philosophy while optimizing for production.
## π Zero Build Development vs Optimized Production
ViewLogic Router's **Zero Build Development** (core philosophy) vs optimized production:
| Mode | Philosophy | Files | Requests | Experience |
|------|------------|-------|----------|------------|
| **Development** | **Zero Build Required** | Separate files | 4 per route | **Real-time, instant changes** |
| **Production** | **Optimized Performance** | Single bundle | 1 per route | **Lightning-fast loading** |
```javascript
// Zero Build Development (Core Philosophy)
ViewLogicRouter({ environment: 'development' }); // Work directly with source files
// Optimized Production
ViewLogicRouter({ environment: 'production' }); // Use pre-built bundles
```
### Zero Build Development Benefits
- β‘ **Instant Changes** - Edit HTML/JS/CSS and see changes immediately
- π **Zero Setup** - No webpack, vite, or build tools required
- π― **True Hot Reload** - Files load directly from src/ folder
- π οΈ **Pure Development** - Focus on code, not build configuration
## πͺΆ Ultra-Lightweight Bundle
ViewLogic Router provides a complete routing solution in an incredibly small package:
### Size Comparison
- **ViewLogic Router**: 13KB gzipped (48KB minified)
- **Vue Router + Auth + i18n + Cache**: 50KB+ gzipped
### What's Included in 13KB
- β
Complete Vue 3 routing system
- β
Authentication & authorization
- β
Internationalization (i18n)
- β
Smart caching system
- β
Query parameter management
- β
Component lazy loading
- β
Layout system
- β
Error handling
- β
Development/production modes
- β
**Automatic data fetching with dataURL**
- β
**Revolutionary DynamicInclude & HtmlInclude components**
- β
**Automatic form handling with variable parameters**
- β
**10+ Built-in UI components (Button, Modal, Card, etc.)**
### Why So Small?
- **Zero Dependencies** - No external libraries required (except Vue 3)
- **Tree-Shakable** - Only includes what you use
- **Optimized Code** - Hand-crafted for minimal bundle size
- **Smart Bundling** - Efficient code organization and minification
### Performance Benefits
- **Faster Load Times** - 70% smaller than typical Vue router setups
- **Better UX** - Instant page loads with minimal JavaScript overhead
- **Mobile Optimized** - Perfect for mobile-first applications
- **CDN Friendly** - Small size ideal for CDN distribution
## π Performance Comparison
### Bundle Size Comparison
| Router System | Bundle Size (Gzipped) | Features Included |
|---------------|----------------------|------------------|
| **ViewLogic Router** | **13KB** | Routing + Auth + i18n + Cache + Query + Components |
| Vue Router | 12KB | Routing only |
| Vue Router + Pinia | 18KB | Routing + State |
| React Router | 15KB | Routing only |
| Next.js Router | 25KB+ | Routing + SSR |
| Nuxt Router | 30KB+ | Routing + SSR + Meta |
### Runtime Performance Comparison
#### Traditional SPA Routing
```
Route Change Process:
βββ 1οΈβ£ Parse route
βββ 2οΈβ£ Load component bundle
βββ 3οΈβ£ Execute component code
βββ 4οΈβ£ Load template (if separate)
βββ 5οΈβ£ Load styles (if separate)
βββ 6οΈβ£ Apply i18n translations
βββ 7οΈβ£ Check authentication
βββ 8οΈβ£ Render component
Total: Multiple operations + Bundle parsing
```
#### ViewLogic Router (Production)
```
Route Change Process:
βββ 1οΈβ£ Load pre-built route bundle (all-in-one)
βββ 2οΈβ£ Render component
Total: Single optimized operation
```
### Performance Advantages
- **π 75% Faster Loading** - Pre-bundled routes vs on-demand compilation
- **π¦ Smaller Footprint** - 13KB includes everything others need 30KB+ for
- **β‘ Instant Navigation** - No build-time compilation in production
- **π― Route-Level Optimization** - Each route is independently optimized
- **πΎ Superior Caching** - Route-level caching vs component-level caching
- **π Zero Hydration** - No server-side rendering complexity
### Why ViewLogic Router Wins
1. **Pre-compilation**: Routes are pre-built, not compiled at runtime
2. **All-in-One Bundles**: View + Logic + Style in single optimized file
3. **Zero Dependencies**: No additional libraries needed for full functionality
4. **Smart Caching**: Route-level caching with intelligent invalidation
5. **Optimized Architecture**: Purpose-built for maximum performance
6. **Revolutionary Components**: DynamicInclude & HtmlInclude for dynamic content loading
## π Revolutionary Built-in Components
ViewLogic Router includes groundbreaking components that revolutionize how you handle dynamic content:
### DynamicInclude Component
```html
<!-- Dynamically load content from any URL -->
<DynamicInclude
page="login"
:use-cache="false"
loading-text="λ‘κ·ΈμΈ νμ΄μ§ λ‘λ© μ€..."
wrapper-class="test-dynamic-include"
:params="{
returnUrl: '/dashboard',
showWelcome: true,
theme: 'compact',
testMode: true
}"
/>
```
**Features:**
- **Dynamic URL Loading** - Load content from any REST API or URL
- **Parameter Injection** - Pass dynamic parameters to the URL
- **Event Handling** - React to loading states and errors
- **Slot Support** - Custom loading and error templates
- **Cache Integration** - Automatic caching with TTL support
### HtmlInclude Component
```html
<!-- Include raw HTML content with Vue reactivity -->
<HtmlInclude
src="/src/views/404.html"
:sanitize="true"
:use-cache="false"
loading-text="μμ ― λ‘λ© μ€..."
wrapper-class="test-html-include"
/>
```
**Features:**
- **Raw HTML Rendering** - Safely render dynamic HTML content
- **XSS Protection** - Built-in HTML sanitization
- **Vue Integration** - HTML content works with Vue reactivity
- **Fallback Support** - Default content when HTML is unavailable
- **Script Execution** - Optional JavaScript execution in HTML content
### Automatic Data Fetching with dataURL
ViewLogic Router includes revolutionary automatic data fetching that eliminates manual API calls in component lifecycle hooks.
#### Single API (Simple Usage)
```javascript
// src/logic/products/list.js
export default {
name: 'ProductsList',
dataURL: '/api/products', // β¨ Magic happens here!
data() {
return {
title: 'Our Products'
// products: [] - No need to declare, auto-populated from API
};
},
mounted() {
// Data is already fetched and available!
console.log('Products loaded:', this.products);
console.log('Loading state:', this.$dataLoading);
},
methods: {
async refreshData() {
// Manual refresh if needed
await this.$fetchData();
}
}
};
```
#### Multiple APIs (Advanced Usage) - π Revolutionary!
```javascript
// src/logic/dashboard/main.js
export default {
name: 'DashboardMain',
dataURL: {
products: '/api/products',
categories: '/api/categories',
stats: '/api/dashboard/stats',
user: '/api/user/profile'
}, // β¨ Multiple APIs with named data!
data() {
return {
title: 'Dashboard'
// products: [], categories: [], stats: {}, user: {}
// All auto-populated from respective APIs!
};
},
mounted() {
// All APIs called in parallel, data available by name!
console.log('Products:', this.products);
console.log('Categories:', this.categories);
console.log('Stats:', this.stats);
console.log('User:', this.user);
console.log('Loading state:', this.$dataLoading);
},
methods: {
async refreshProducts() {
// Refresh specific API only
await this.$fetchData('products');
},
async refreshStats() {
// Refresh specific API only
await this.$fetchData('stats');
},
async refreshAllData() {
// Refresh all APIs
await this.$fetchAllData();
}
}
};
```
**Features:**
- **Zero-Config API Calls** - Just define `dataURL` and data is automatically fetched
- **π Multiple API Support** - Define multiple APIs with custom names
- **π Parallel Processing** - Multiple APIs called simultaneously for best performance
- **π― Selective Refresh** - Refresh specific APIs independently
- **Query Parameter Integration** - Current route parameters are automatically sent to all APIs
- **Loading State Management** - `$dataLoading` property automatically managed
- **Advanced Error Handling** - Per-API error handling with detailed events
- **Named Data Storage** - Each API result stored with its defined name
- **Event Support** - `@data-loaded` and `@data-error` events with detailed info
### Why These Components Are Revolutionary
**Traditional Approach**: 30+ lines of loading states, error handling, and manual API calls.
**ViewLogic Approach**: `dataURL: '/api/products'` - That's it! Data automatically fetched and available as `this.products`.
### Common Use Cases
- **Single API**: `dataURL: '/api/products'` - Product listings, user profiles, articles
- **Multiple APIs**: `dataURL: { stats: '/api/stats', users: '/api/users' }` - Dashboards, admin panels
- **Dynamic Content**: `<DynamicInclude page="login" :params="{ theme: 'compact' }" />`
- **HTML Includes**: `<HtmlInclude src="/widgets/weather.html" :sanitize="true" />`
### Advantages
- β
**Auto Data Fetching** with `dataURL` property (others: manual logic)
- β
**Parameter Integration** - Query params sent automatically
- β
**Loading States** - `$dataLoading` auto-managed
- β
**Built-in Security** - HTML sanitization included
- β
**Zero Setup** - Works immediately without configuration
## π Automatic Form Handling with Variable Parameters
ViewLogic Router includes revolutionary automatic form handling that eliminates the need for manual form submission logic. Just define your forms with `action` attributes and the router handles the rest!
### Basic Form Handling
```html
<!-- src/views/contact.html -->
<div class="contact-page">
<h1>Contact Us</h1>
<form action="/api/contact" method="POST">
<input type="text" name="name" required placeholder="Your Name">
<input type="email" name="email" required placeholder="Your Email">
<textarea name="message" required placeholder="Your Message"></textarea>
<button type="submit">Send Message</button>
</form>
</div>
```
```javascript
// src/logic/contact.js
export default {
name: 'ContactPage',
mounted() {
// Forms are automatically bound - no additional code needed!
// Form submission will automatically POST to /api/contact
console.log('Form handling is automatic!');
}
};
```
### Variable Parameter Forms - π Revolutionary!
The most powerful feature is **variable parameter support** in action URLs. You can use simple template syntax to inject dynamic values:
```html
<!-- Dynamic form actions with variable parameters -->
<form action="/api/users/{userId}/posts" method="POST"
data-success="handlePostSuccess"
data-error="handlePostError">
<input type="text" name="title" required placeholder="Post Title">
<textarea name="content" required placeholder="Post Content"></textarea>
<button type="submit">Create Post</button>
</form>
<!-- Order update with dynamic order ID -->
<form action="/api/orders/{orderId}/update" method="PUT"
data-success="orderUpdated"
data-redirect="/orders">
<input type="number" name="quantity" required>
<select name="status">
<option value="pending">Pending</option>
<option value="processing">Processing</option>
<option value="completed">Completed</option>
</select>
<button type="submit">Update Order</button>
</form>
<!-- File upload support -->
<form action="/api/profile/{userId}/avatar" method="POST" enctype="multipart/form-data"
data-success="avatarUploaded">
<input type="file" name="avatar" accept="image/*" required>
<button type="submit">Upload Avatar</button>
</form>
```
```javascript
// Component logic - parameters are resolved automatically
export default {
name: 'UserProfile',
data() {
return {
userId: 123, // {userId} will be replaced with this value
orderId: 456 // {orderId} will be replaced with this value
};
},
methods: {
handlePostSuccess(response) {
console.log('Post created successfully!', response);
},
orderUpdated(response) {
console.log('Order updated!', response);
}
}
};
```
### How Parameter Resolution Works
Parameters are resolved automatically from multiple sources in this order:
1. **Route Parameters**: `this.getParam('paramName')` - from URL query parameters
2. **Component Data**: `this.paramName` - from component's data properties
3. **Computed Properties**: `this.paramName` - from component's computed properties
```javascript
// Component example
export default {
name: 'UserProfile',
data() {
return {
userId: 123, // Available as {userId} in action URLs
productId: 456 // Available as {productId} in action URLs
};
},
computed: {
currentOrderId() { // Available as {currentOrderId} in action URLs
return this.getParam('orderId') || this.defaultOrderId;
}
},
mounted() {
// Route parameters also work: /user-profile?userId=789
// {userId} will use 789 from URL, or fall back to data() value of 123
}
};
```
### Event Handlers
```html
<form action="/api/subscribe" method="POST"
data-success="subscriptionSuccess" data-error="subscriptionError">
<input type="email" name="email" required>
<button type="submit">Subscribe</button>
</form>
```
```javascript
export default {
methods: {
subscriptionSuccess(response) { this.$toast('Success!', 'success'); },
subscriptionError(error) { this.$toast('Failed!', 'error'); }
}
};
```
### Form Options
```html
<form action="/api/resource/{id}" method="POST"
data-success="handleSuccess" data-error="handleError"
data-redirect="/success" data-confirm="Sure?"
enctype="multipart/form-data">
<input name="title" required>
<input type="file" name="file" accept=".pdf">
<button type="submit">Submit</button>
</form>
```
### Authentication Integration
```html
<!-- Auth tokens automatically included for authenticated users -->
<form action="/api/protected/resource" method="POST">
<input name="data" required>
<button type="submit">Save</button>
</form>
<!-- Authorization: Bearer <token> header added automatically -->
```
### Form Validation
```html
<!-- HTML5 + custom validation -->
<form action="/api/register" method="POST">
<input type="email" name="email" required pattern="...">
<input type="password" name="password" minlength="8" required>
<button type="submit">Register</button>
</form>
```
### Real-World Form Examples
```html
<!-- User profile with dynamic parameters -->
<form action="/api/users/{userId}" method="PUT" data-success="profileUpdated">
<input name="firstName" required>
<button type="submit">Update</button>
</form>
<!-- Order management -->
<form action="/api/orders/{orderId}/status" method="PUT">
<select name="status" required>
<option value="pending">Pending</option>
<option value="shipped">Shipped</option>
</select>
<button type="submit">Update</button>
</form>
```
### Form Handling Advantages
- β
**Zero Setup** - Just add `action` attribute vs manual event handlers
- β
**Variable Parameters** - `{userId}` template syntax vs manual interpolation
- β
**Auto Authentication** - Tokens injected automatically
- β
**File Uploads** - Automatic multipart support
- β
**Built-in Validation** - HTML5 + custom functions
### Code Comparison
**Traditional**: 30+ lines of boilerplate for forms, API calls, loading states
**ViewLogic**: 5 lines with `action` attribute + callback method
**Result**: 80% less code, more features included
## π Query-Based Parameter System: Revolutionary Simplicity
ViewLogic Router's **Query-Based Parameter System** is a key feature that eliminates routing complexity:
**Philosophy**: **Everything is query-based** - no complex path parameters like `/users/:id`. Just simple, clean URLs: `/users?id=123`.
### Revolutionary Benefits
1. **π Simple URLs**: `/product?id=123&category=electronics` (clear and readable)
2. **π― Consistent Access**: Always use `this.getParam('id')` - never mix path/query paradigms
3. **β‘ No Route Configuration**: No complex route definitions or parameter mappings needed
4. **π SEO Friendly**: Descriptive parameter names make URLs self-documenting
5. **π Universal Compatibility**: Query parameters work everywhere - no framework lock-in
### Simple Usage Example
```javascript
// Navigate - simple and intuitive
this.navigateTo('products', { id: 123, category: 'electronics' });
// β /products?id=123&category=electronics
// Access parameters - always the same way
export default {
mounted() {
const id = this.getParam('id'); // Get parameter
const category = this.getParam('category', 'all'); // With default
const allParams = this.getParams(); // Get all parameters
}
};
```
### Why Query-Based is Revolutionary
**Traditional Routers**: Complex path parameters (`/users/:id/posts/:postId`) require route configuration, parameter extraction logic, and mixed paradigms.
**ViewLogic Router**: Simple query parameters (`/users?id=123&postId=456`) work universally with consistent `getParam()` access.
## π‘οΈ Error Handling
Built-in comprehensive error handling with automatic 404 detection, graceful component loading failures, and parameter validation with fallbacks.
## π Production Deployment
1. **Build**: `npm run build` - Combines view + logic + style into optimized route bundles
2. **Deploy**: Set `environment: 'production'` and use CDN or local files
3. **Structure**: Deploy `routes/`, `css/`, `i18n/` folders (exclude `src/`)
**CDN Usage:**
```html
<script src="https://cdn.jsdelivr.net/npm/viewlogic/dist/viewlogic-router.umd.js"></script>
<script>
ViewLogicRouter({ environment: 'production' }).mount('#app');
</script>
```
## π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## π License
MIT License - see the [LICENSE](LICENSE) file for details.
## π Author
Created by [hopegiver](https://github.com/hopegiver)
## π Support
- π Issues: [GitHub Issues](https://github.com/hopegiver/viewlogic/issues)
- π¬ Discussions: [GitHub Discussions](https://github.com/hopegiver/viewlogic/discussions)
---
<p align="center">Made with β€οΈ for the Vue.js community</p>