Riot v4兼容视图路由选型咨询:寻求替代方案
Hey there! I totally get the frustration of trying to find routing tools that work with Riot v4 when go-to options like riot-router and riot-view-router are stuck on v3 with no clear update timeline. Here are a few solid alternatives you can use right now:
1. Roll Your Own Simple Routing with the Browser History API
This is the most lightweight approach—no extra dependencies needed, just leveraging the native browser API to handle route changes directly in your root Riot component:
Example Implementation
Root Component (app.riot):
<app> <nav> <a href="/" onclick={ navigate }>Home</a> <a href="/about" onclick={ navigate }>About</a> <a href="/contact" onclick={ navigate }>Contact</a> </nav> <!-- Render the active view component --> <component is={ currentView }></component> <script> export default { state: { currentView: 'home-page' }, onMounted() { // Initialize with the current path this.handleRoute(window.location.pathname); // Listen for back/forward button clicks window.addEventListener('popstate', () => { this.handleRoute(window.location.pathname); }); }, handleRoute(path) { // Map paths to your component names switch(path) { case '/': this.state.currentView = 'home-page'; break; case '/about': this.state.currentView = 'about-page'; break; case '/contact': this.state.currentView = 'contact-page'; break; default: this.state.currentView = '404-page'; } // Trigger a component update this.update(); }, navigate(e) { e.preventDefault(); const path = e.target.getAttribute('href'); // Update the browser history window.history.pushState({}, '', path); // Handle the new route this.handleRoute(path); } } </script> </app>
This gives you full control over routing logic and works seamlessly with Riot v4's component model.
2. Integrate a Lightweight Third-Party Routing Library
Framework-agnostic routing libraries play nicely with Riot v4 and handle edge cases like query parameters or dynamic routes out of the box. Two popular options are page.js and Navigo:
Example with Page.js
First install the library:
npm install page --save
Then set it up in your root component:
<app> <nav> <a href="/" onclick={ handleNav }>Home</a> <a href="/about" onclick={ handleNav }>About</a> </nav> <component is={ currentView }></component> <script> import page from 'page'; export default { state: { currentView: 'home-page' }, onMounted() { // Define route handlers page('/', () => { this.state.currentView = 'home-page'; this.update(); }); page('/about', () => { this.state.currentView = 'about-page'; this.update(); }); page('*', () => { this.state.currentView = '404-page'; this.update(); }); // Start listening for route changes page.start(); }, onUnmounted() { // Clean up when the component is removed page.stop(); }, handleNav(e) { e.preventDefault(); page.show(e.target.getAttribute('href')); } } </script> </app>
3. Build a Reusable Riot Router Component
For larger apps, create a dedicated <router> component to encapsulate routing logic, making it easier to reuse and extend across your application:
Example Router Component (router.riot)
<router> <component is={ currentView } route={ currentRoute }></component> <script> export default { state: { routes: {}, currentPath: window.location.pathname }, onMounted() { window.addEventListener('popstate', () => { this.state.currentPath = window.location.pathname; this.updateActiveRoute(); }); this.updateActiveRoute(); }, updateActiveRoute() { // Find the matching route (fallback to 404) const matchedPath = Object.keys(this.state.routes).find( path => path === this.state.currentPath || path === '*' ) || '*'; this.currentView = this.state.routes[matchedPath]; this.currentRoute = { path: this.state.currentPath }; this.update(); }, // Method to add routes from parent components registerRoutes(newRoutes) { this.state.routes = { ...this.state.routes, ...newRoutes }; this.updateActiveRoute(); }, // Navigation method to use in child components navigateTo(path) { window.history.pushState({}, '', path); this.state.currentPath = path; this.updateActiveRoute(); } } </script> </router>
Using the Router in Your Root Component
<app> <nav onclick={ handleNav }> <a data-path="/">Home</a> <a data-path="/dashboard">Dashboard</a> </nav> <router ref="appRouter"></router> <script> export default { onMounted() { // Register your app's routes this.$refs.appRouter.registerRoutes({ '/': 'home-page', '/dashboard': 'dashboard-page', '*': '404-page' }); }, handleNav(e) { const path = e.target.getAttribute('data-path'); if (path) { e.preventDefault(); this.$refs.appRouter.navigateTo(path); } } } </script> </app>
This approach keeps your routing logic centralized and scalable as your app grows.
All these options work reliably with Riot v4 and don't require waiting for updated Riot-specific routing modules. They're flexible enough to handle everything from simple single-page apps to more complex multi-view applications.
内容的提问来源于stack exchange,提问作者James

