UNPKG

viewlogic

Version:

A lightweight, file-based routing system for Vue 3 applications with zero build configuration

938 lines (785 loc) β€’ 33.5 kB
# 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 <!DOCTYPE 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 <!DOCTYPE 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>