使用GetX实现GetPage中间件

前言

GetX 中间件(Middleware)是 GetX 框架中的一种机制,用于在页面导航时对用户进行权限控制、数据预加载、页面访问条件设置等。通过使用中间件,可以有效地控制用户的访问流程,并在适当条件下引导用户到所需页面。

这篇文文章主要介绍下GetX中间件的用法。

一、中间件的作用

中间件可用于以下场景:

  1. 权限控制:例如判断用户是否登录,如果未登录则跳转到登录页面。
  2. 数据预加载:在页面进入前进行数据的加载和检查。
  3. 访问条件控制:例如限制页面访问的时间或条件。

二、使用 GetMiddleware 的基本步骤

  1. 创建一个继承自 GetMiddleware 的自定义中间件类。

  2. 在类中重写 redirect、onPageCalled、onPageDispose 等方法,以便在导航时执行相应逻辑。

  3. 在 GetPage 的 middlewares 参数中加入自定义的中间件类,实现页面访问的中间件逻辑。

三、GetMiddleware 常用方法

|------------------|-----------------------------------------------------------------------|
| 方法 | 作用说明 |
| redirect | 重定向页面到其他路由。通常用于在进入页面前进行权限判断,返回 RouteSettings 对象指定重定向页面,返回 null 则不重定向。 |
| onPageCalled | 在页面被调用时触发,适合用于进行数据预加载。 |
| onPageDispose | 在页面被销毁时触发,用于清理资源。 |
| onBindingsStart | 在页面绑定(Bindings)初始化时触发,适合进行依赖注入等操作。 |
| onPageBuildStart | 在页面构建前触发。 |
| onPageBuilt | 在页面构建完成后触发。 |

四、中间件实现登录检查的例子

我们可以通过下面的一个例子来看一下GetX中间件的用法。

在我们的实例代码中,我们会实现以下功能:

  1. 用户未登录时访问个人资料页面会跳转到登录页面。
  2. 登录后直接跳转到个人资料页面,点击退出登录后再返回登录页面。

图1.使用GetX实现中间件登陆

我们看一下具体的实现步骤:

1.创建 AuthController

AuthController 用于管理用户的登录状态,并保存状态信息(例如通过 SharedPreferences)。

Dart 复制代码
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';

class AuthController extends GetxController {
  var isLoggedIn = false.obs;

  // 初始化控制器,检查登录状态
  Future<AuthController> init() async {
    final prefs = await SharedPreferences.getInstance();
    isLoggedIn.value = prefs.getBool('isLoggedIn') ?? false;
    return this;
  }

  void login() async {
    isLoggedIn.value = true;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool('isLoggedIn', true); // 保存登录状态
  }

  void logout() async {
    isLoggedIn.value = false;
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('isLoggedIn'); // 清除登录状态
  }
}

2.创建中间件 AuthMiddleware

Dart 复制代码
import 'package:get/get.dart';
import 'auth_controller.dart';

class AuthMiddleware extends GetMiddleware {
  @override
  RouteSettings? redirect(String? route) {
    final authController = Get.find<AuthController>();
    // 如果用户未登录,则重定向到登录页面
    return authController.isLoggedIn.value ? null : const RouteSettings(name: '/login');
  }
}

3.设置路由

在 main.dart 中定义路由和页面导航逻辑,并将 AuthMiddleware 添加到 ProfilePage 的路由中。

Dart 复制代码
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'auth_controller.dart';
import 'auth_middleware.dart';
import 'get_middle_ware_home_page.dart';
import 'login_page.dart';
import 'profile_page.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Get.putAsync(() => AuthController().init()); // 初始化 AuthController
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      initialRoute: '/', // 初始路由
      getPages: [
        GetPage(name: '/', page: () => const GetMiddleWareHomePage()),
        GetPage(name: '/login', page: () => LoginPage()),
        GetPage(name: '/profile', page: () => ProfilePage(), middlewares: [AuthMiddleware()]),
      ],
    );
  }
}

4.创建各个页面

get_middle_ware_home_page.dart

Dart 复制代码
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class GetMiddleWareHomePage extends StatelessWidget {
  const GetMiddleWareHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home Page')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Get.toNamed('/profile'); // 导航到 Profile 页面
          },
          child: const Text('Go to Profile'),
        ),
      ),
    );
  }
}

profile_page.dart

Dart 复制代码
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'auth_controller.dart';

class ProfilePage extends StatelessWidget {
  const ProfilePage({super.key});

  @override
  Widget build(BuildContext context) {
    final authController = Get.find<AuthController>();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile Page'),
        actions: [
          IconButton(
            icon: const Icon(Icons.logout),
            onPressed: () {
              authController.logout();
              Get.offAllNamed('/login'); // 退出后跳转到登录页面
            },
          ),
        ],
      ),
      body: const Center(child: Text('Welcome to your profile!')),
    );
  }
}

login_page.dart

Dart 复制代码
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'auth_controller.dart';

class LoginPage extends StatelessWidget {
  LoginPage({super.key});

  final AuthController authController = Get.find();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Login Page')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            authController.login();
            Get.offAllNamed('/profile'); // 登录后直接跳转到 Profile 页面
          },
          child: const Text('Login'),
        ),
      ),
    );
  }
}
相关推荐
风华圆舞5 小时前
在 Flutter 鸿蒙项目里接入语音识别的完整思路
flutter·语音识别·harmonyos
番茄去哪了6 小时前
神领物流面试题(一)
java·大数据·中间件
风华圆舞7 小时前
鸿蒙 + Flutter 下如何让 HarmonyOS 能力真正服务于 AI 体验
人工智能·flutter·harmonyos
BreezeDove8 小时前
【Android】Flutter3.35项目启动超时问题
android·flutter
念何架构之路9 小时前
消息中间件
中间件
风华圆舞9 小时前
鸿蒙 MICROPHONE 权限在 Flutter 项目里怎么处理
flutter·华为·harmonyos
都说名字长不会被发现9 小时前
Spring Boot Starter 中间件账号密码加密方案设计与实现
java·spring boot·后端·中间件
愚者Pro1 天前
切换本地 Flutter SDK 版本
flutter
TT_Close1 天前
别再复制旧 Flutter 工程了,真正拖慢你的不是业务代码
flutter·npm·visual studio code
风华圆舞1 天前
鸿蒙 + Flutter 下 AI 助手为什么要支持流式输出
人工智能·flutter·harmonyos