如何使用GetX实现左侧侧边栏固定的Nested Route?
固定侧边栏+右侧页面切换的GetX实现方案
核心思路
将Dashboard作为父容器,左侧固定侧边栏组件,右侧通过GetX状态管理动态切换页面内容,避免全局路由跳转导致侧边栏重绘。以下是完整实现代码:
1. 创建页面管理Controller
用GetX Controller维护当前选中页面索引及对应页面列表:
class DashboardController extends GetxController { // 响应式的当前页面索引 final currentPageIndex = 0.obs; // 侧边栏对应的页面集合 final pages = const [ HomePage(), SettingsPage(), ProfilePage(), ]; // 切换页面方法 void switchPage(int index) { currentPageIndex.value = index; } }
2. 实现固定侧边栏组件
侧边栏通过Obx监听Controller的索引变化,同步选中状态:
class Sidebar extends StatelessWidget { const Sidebar({super.key}); @override Widget build(BuildContext context) { final controller = Get.find<DashboardController>(); return Container( width: 250, color: Colors.grey[800], child: Column( children: [ const SizedBox(height: 40), Obx(() => ListTile( leading: const Icon(Icons.home, color: Colors.white), title: const Text('首页', style: TextStyle(color: Colors.white)), selected: controller.currentPageIndex.value == 0, selectedTileColor: Colors.grey[700], onTap: () => controller.switchPage(0), )), Obx(() => ListTile( leading: const Icon(Icons.settings, color: Colors.white), title: const Text('设置', style: TextStyle(color: Colors.white)), selected: controller.currentPageIndex.value == 1, selectedTileColor: Colors.grey[700], onTap: () => controller.switchPage(1), )), Obx(() => ListTile( leading: const Icon(Icons.person, color: Colors.white), title: const Text('个人中心', style: TextStyle(color: Colors.white)), selected: controller.currentPageIndex.value == 2, selectedTileColor: Colors.grey[700], onTap: () => controller.switchPage(2), )), ], ), ); } }
3. 构建Dashboard主页面
主页面组合侧边栏与右侧页面容器,通过Obx响应索引变化切换页面:
class Dashboard extends StatelessWidget { const Dashboard({super.key}); @override Widget build(BuildContext context) { // 初始化Controller(也可在main.dart中全局初始化) Get.put(DashboardController()); final controller = Get.find<DashboardController>(); return Scaffold( body: Row( children: [ // 固定显示侧边栏 const Sidebar(), // 右侧页面容器,占满剩余宽度 Expanded( child: Obx(() => controller.pages[controller.currentPageIndex.value]), ), ], ), ); } }
4. 示例子页面
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Center(child: Text('首页内容')); } } class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); @override Widget build(BuildContext context) { return Center(child: Text('设置页面内容')); } } class ProfilePage extends StatelessWidget { const ProfilePage({super.key}); @override Widget build(BuildContext context) { return Center(child: Text('个人中心内容')); } }
扩展:通过命名路由切换页面
如果需要从子页面内部触发切换,可在Controller中添加路由映射逻辑:
// 在DashboardController中新增 final pageRouteMap = { '/home': 0, '/settings': 1, '/profile': 2, }; void switchPageByRoute(String routeName) { currentPageIndex.value = pageRouteMap[routeName] ?? 0; }
在子页面中调用:
Get.find<DashboardController>().switchPageByRoute('/settings');
内容的提问来源于stack exchange,提问作者Thura Khant Thein
相关产品推荐
相关产品推荐

