Flutter路由

路由作为一种页面切换的能力,非常重要。Flutter 中路由管理有几个重要的点。

Navigator 1.0:Flutter 早期路由系统,侧重于移动端 ,命令式编程风格,使用 Navigator.push() 和 Navigator.pop() 等方法来管理路由栈。

Navigator 2.0:Flutter1.22 版本以后新增,侧重于桌面端/网页端,声明式编程风格,使用 Router 和 RouteInformationParser 等类来描述和管理路由树。

Flutter路由重要的类

1.Route:应用程序页面的抽象, Navigator 管理 Route。

2.Navigator:负责路由管理的重要类,通过 push 和 pop 进行页面跳转。

Flutter 跳转方式

动态路由

适于单次导航的场景,直接在代码中创建和导航的路由。

Dart 复制代码
Navigator.push(context,
    MaterialPageRoute(builder: (context) => RouterPageA()));
Dart 复制代码
   Navigator.pop(context);
Dart 复制代码
import 'package:flutter/material.dart';

import 'dart_test_router1.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test Navigator"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("Test MaterialPageRoute"),
            ElevatedButton(
              onPressed: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => RouterPageA()));
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("RouterPageA"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("Test Navigator.pop"),
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}

Navigator.push有两个参数,一个是BuildContext,另一个是Route。代码中使用的是MaterialPageRoute,执行与对应平台风格一致的切换动画(android 与 ios平台不同)。如果使用 CupertinoPageRoute,页面切换效果是左右滑动。

PageRoute可以自定义,实现自定义页面切换的动画和行为。如果想自定义下过渡动画,使用 PageRouteBuilder 创建自定义路由,通过 pageBuilder 和 transitionsBuilder 属性来定义页面和过渡动画。

通过 pageBuilder 实现页面渐入动画

Dart 复制代码
                Navigator.of(context).push(PageRouteBuilder(
                    pageBuilder: (context, animation, secondaryAnimation) {
                  return FadeTransition(
                      opacity: animation, child: const RouterPageA());
                }));

pageBuilder + transitionsBuilder 实现过渡动画

Dart 复制代码
                Navigator.of(context).push(PageRouteBuilder(
                    pageBuilder: (context, animation, secondaryAnimation) =>
                        const RouterPageA(),
                    transitionsBuilder:
                        (context, animation, secondaryAnimation, child) {
                     //动画的起始位置,轴y方向屏幕下侧偏移起点
                      var start = const Offset(0, 1);
                     //动画的结束位置,0表示没有偏移
                      var end = Offset.zero;
                      //动画曲线,easeInOut 表示开始慢,中间加速,结束慢
                      var curve = Curves.easeInOut;
                      // 创建一个从begin到end的补间动画,.chain 表示与曲线结合
                      var tween = Tween(begin: start, end: end)
                          .chain(CurveTween(curve: curve));
                       // SlideTransition 是一个动画Widget
                      return SlideTransition(
                          position: animation.drive(tween), child: child);
                    }));

静态路由

静态路由需要提前注册,首先给每个路由定义一个名称,通过这个名称来导航到对应的路由。

在应用根级别 (MaterialApp 或者 CupertinoApp ) 中定义路由,使用routes参数将路由名称映射到对应的Widget。

不带参数与返回值案例

Dart 复制代码
Navigator.of(context).pushNamed("/dart_test_router1");
Dart 复制代码
import 'package:flutter/material.dart';

import 'dart_test_router1.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test Router Demo",
      theme: ThemeData(
        useMaterial3: false,
        primarySwatch: Colors.blue,
        textButtonTheme: const TextButtonThemeData(
          
          style: ButtonStyle(splashFactory: NoSplash.splashFactory),
        ),
      ),
      home: const RealTestStaticRouterPage(),
      routes: {
      //  "/": (context) => const RealTestStaticRouterPage(),
        "/dart_test_router1": (context) => const RouterPageA()
      },
     // initialRoute: "/",
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("TEST STATIC ROUTER PAGE"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("Test Static Router Page"),
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).pushNamed("/dart_test_router1");
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }

带参数与返回值

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

import 'dart_test_router1.dart';
import 'dart_test_router3.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test Router Demo",
      theme: ThemeData(
        useMaterial3: false,
        primarySwatch: Colors.blue,
        textButtonTheme: const TextButtonThemeData(
          // 鍘绘帀 TextButton 鐨勬按娉㈢汗鏁堟灉
          style: ButtonStyle(splashFactory: NoSplash.splashFactory),
        ),
      ),
      home: const RealTestStaticRouterPage(),
      routes: {
        //  "/": (context) => const RealTestStaticRouterPage(),
        "/dart_test_router1": (context) => const RouterPageA(),
        "/dart_test_router3": (context) => const RouterPage3()
      },
      // initialRoute: "/",
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("TEST STATIC ROUTER PAGE"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("Test Static Router Page"),
            ElevatedButton(
              onPressed: () async {
                var result = await Navigator.of(context).pushNamed(
                    "/dart_test_router3",
                    arguments: {"title": "Hello"});
                print(result);
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
Dart 复制代码
import 'package:flutter/material.dart';

class RouterPage3 extends StatefulWidget {
  const RouterPage3({super.key});

  @override
  State<StatefulWidget> createState() {
    return _RouterPage3State();
  }
}

class _RouterPage3State extends State<RouterPage3> {
  @override
  Widget build(BuildContext context) {
    var args =
        ModalRoute.of(context)?.settings.arguments as Map<String, dynamic>?;
    final title = args?['title'] ?? "DEFAULT TITLE";

    return Scaffold(
      appBar: AppBar(
        title: Text("RouterPageA"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("GET TITLE===========銆?title"),
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context, "I went from RouterPage3");
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}
Dart 复制代码
2024-09-12 10:01:46.569 25438-25629 flutter  I  I went from RouterPage3

路由操作

路由替换

像登录页跳首页的场景,我们希望页面跳转成功后,回到上上个页面。我们可以通过pushReplacement、pushReplacementNamed实现。

API一:动态路由替换

Dart 复制代码
Navigator.of(context).pushReplacement(
                    MaterialPageRoute(builder: (context) => RouterPageA()));

API二:静态路由替换

Dart 复制代码
         var result = await Navigator.of(context).pushReplacementNamed(
                    "/dart_test_router3",
                    arguments: {"title": "Hello"});

新路由入栈+移除之前的路由,直到条件满足

pushAndRemoveUntil 将给定路由推送给Navigator,删除先前的路由,直到该函数的参数predicate返回true为才停止。

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

import 'dart_test_router1.dart';
import 'dart_test_router3.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test pushAndRemoveUntil",
      theme: ThemeData(
          useMaterial3: false,
          primarySwatch: Colors.blue,
          textButtonTheme: const TextButtonThemeData(
            style: ButtonStyle(splashFactory: NoSplash.splashFactory),
          )),
      home: const RealTestRouterPage4(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test pushAndRemoveUntil"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text("test pushAndRemoveUntil"),
              ElevatedButton(
                onPressed: () {
                  Navigator.pushAndRemoveUntil(
                      context,
                      MaterialPageRoute(builder: (context) => RouterPageA()),
                      (Route<dynamic> route) => route.isFirst);
                },
                child: Text("Click ElevatedButton"),
                style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blue,
                    foregroundColor: Colors.white,
                    elevation: 10,
                    minimumSize: Size(double.infinity, 50),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10))),
              )
            ]),
      ),
    );
  }
}

这个方式是跳转到某个页面,然后移除路由直到...为止

路由出栈,直到条件满足

在flutter 路由跳转中,我们想要回到特定的一个页面 比如:从 A -> B-> C ->D,我们向从 D页面 pop至 B 页面。我们可以使用 popUtil方法回到 B 页面。

popUntil 反复执行pop 直到该函数的参数predicate返回true为止。

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

import 'dart_test_router6.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Test popUntil TestRouterPage5",
      theme: ThemeData(
          useMaterial3: false,
          primarySwatch: Colors.blue,
          textButtonTheme: const TextButtonThemeData(
            style: ButtonStyle(splashFactory: NoSplash.splashFactory),
          )),
      home: const RealTestRouterPage5(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test popUntil TestRouterPage5"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text("test popUntil TestRouterPage5"),
              ElevatedButton(
                onPressed: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => TestRouterPage6()));
                },
                child: Text("Click ElevatedButton"),
                style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blue,
                    foregroundColor: Colors.white,
                    elevation: 10,
                    minimumSize: Size(double.infinity, 50),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10))),
              )
            ]),
      ),
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

import 'dart_test_router7.dart';

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

  @override
  Widget build(BuildContext context) {
    return RealTestRouterPage6();
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test popUntil TestRouterPage6"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text("test popUntil TestRouterPage6"),
              ElevatedButton(
                onPressed: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => TestRouterPage7()));
                },
                child: Text("Click ElevatedButton"),
                style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blue,
                    foregroundColor: Colors.white,
                    elevation: 10,
                    minimumSize: Size(double.infinity, 50),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10))),
              )
            ]),
      ),
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return RealTestRouterPage7();
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test popUntil TestRouterPage7"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text("test popUntil TestRouterPage7"),
              ElevatedButton(
                onPressed: () {
                  Navigator.of(context)
                      .popUntil((Route<dynamic> route) => route.isFirst);
                },
                child: Text("Click ElevatedButton"),
                style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blue,
                    foregroundColor: Colors.white,
                    elevation: 10,
                    minimumSize: Size(double.infinity, 50),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(10))),
              )
            ]),
      ),
    );
  }
}

上面的代码中调用Navigator.of(context)

.popUntil((Route<dynamic> route) => route.isFirst);直接回到了 TestRouterPage5。

复制代码

删除指定路由

获得当前路由

Dart 复制代码
ModalRoute.of(context);

移除指定路由

Dart 复制代码
if (route != null) {
  Navigator.of(context).removeRoute(route);
}

移除指定路由下方的单个路由

Dart 复制代码
if (route != null) {
  Navigator.of(context).removeRouteBelow(route);
}

页面传参与数据回传

Dart 复制代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:gsy_flutter_demo/widget/dart_test_router2.dart';

import 'dart_test_router1.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test Navigator"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text("Test MaterialPageRoute"),
            ElevatedButton(
              onPressed: () async {
                String backContent = await Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) => RouterPage2(title: "Custom Title")));
                print(backContent);
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}
Dart 复制代码
import 'package:flutter/material.dart';

class RouterPage2 extends StatefulWidget {
  final String title;

  const RouterPage2({super.key, required this.title});

  @override
  State<StatefulWidget> createState() {
    return _RouterPage2State();
  }
}

class _RouterPage2State extends State<RouterPage2> {
  @override
  Widget build(BuildContext context) {
    var widgitTitle = widget.title;

    return Scaffold(
      appBar: AppBar(
        title: Text("RouterPageA"),
      ),
      body: Container(
        alignment: Alignment.center,
        margin: const EdgeInsets.all(10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("GET TITLE===========銆?widgitTitle"),
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context, "I went from RouterPageA");
              },
              child: Text("Click ElevatedButton"),
              style: ElevatedButton.styleFrom(
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  elevation: 10,
                  minimumSize: Size(double.infinity, 50),
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(10))),
            )
          ],
        ),
      ),
    );
  }
}

Dart 复制代码
2024-09-11 14:51:16.211 24765-24840 flutter I  I went from RouterPageA

Navigator 的核心是对路由栈的管理。当你调用 Navigator.push 时,一个新的路由被创建并推入栈顶;当你调用 Navigator.pop 时,栈顶的路由被移除。

Dart 复制代码
  const Navigator({
    super.key,
    this.pages = const <Page<dynamic>>[],
    this.onPopPage,
    this.initialRoute,
    this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,
    this.onGenerateRoute,
    this.onUnknownRoute,
    this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),
    this.reportsRouteUpdateToEngine = false,
    this.clipBehavior = Clip.hardEdge,
    this.observers = const <NavigatorObserver>[],
    this.requestFocus = true,
    this.restorationScopeId,
    this.routeTraversalEdgeBehavior = kDefaultRouteTraversalEdgeBehavior,
  });

#Navigator.push

Dart 复制代码
  @optionalTypeArgs
  static Future<T?> push<T extends Object?>(BuildContext context, Route<T> route) {
    return Navigator.of(context).push(route);
  }

Navigator.push 调用Navigator.of(context).push(route),内部 调用NavigatorState 的 push 方法:

Dart 复制代码
  @optionalTypeArgs
  Future<T?> push<T extends Object?>(Route<T> route) {
    _pushEntry(_RouteEntry(route, pageBased: false, initialState: _RouteLifecycle.push));
    return route.popped;
  }

#NavigatorState

Dart 复制代码
  void _pushEntry(_RouteEntry entry) {
    assert(!_debugLocked);
    assert(() {
      _debugLocked = true;
      return true;
    }());
    assert(entry.route._navigator == null);
    assert(entry.currentState == _RouteLifecycle.push);
    _history.add(entry);
    _flushHistoryUpdates();
    assert(() {
      _debugLocked = false;
      return true;
    }());
    _afterNavigation(entry.route);
  }

这里发生了一系列操作:

  • _history.add(route) : 将 新路由 添加到 路由栈 中。
  • route.install() : 安装路由,将页面挂载到 widget 树上。
  • route.didPush() : 通知 路由 已经被推入 栈顶 。
  • _cancelActivePointers() : 取消所有正在进行的触摸事件,防止发生意外事件。
  • route.didChange() : 通知 路由 状态发生变化。

push 方法返回一个 Future,该 Future 会在路由完成push操作时完成。

#Navigator.pop

Dart 复制代码
 Navigator.of(context).pop();
Dart 复制代码
  @optionalTypeArgs
  void pop<T extends Object?>([ T? result ]) {
    assert(!_debugLocked);
    assert(() {
      _debugLocked = true;
      return true;
    }());
    final _RouteEntry entry = _history.lastWhere(_RouteEntry.isPresentPredicate);
    if (entry.pageBased) {
      if (widget.onPopPage!(entry.route, result) && entry.currentState == _RouteLifecycle.idle) {
        // The entry may have been disposed if the pop finishes synchronously.
        assert(entry.route._popCompleter.isCompleted);
        entry.currentState = _RouteLifecycle.pop;
      }
      entry.route.onPopInvoked(true);
    } else {
      entry.pop<T>(result);
      assert (entry.currentState == _RouteLifecycle.pop);
    }
    if (entry.currentState == _RouteLifecycle.pop) {
      _flushHistoryUpdates(rearrangeOverlay: false);
    }
    assert(entry.currentState == _RouteLifecycle.idle || entry.route._popCompleter.isCompleted);
    assert(() {
      _debugLocked = false;
      return true;
    }());
    _afterNavigation(entry.route);
  }
  • history.lastWhere:找到最后一个处于 "存在"状态 的路由条目。
  • entry.pageBased:路由是否是基于页面的。
  • widget.onPopPage:执行页面pop操作。
  • entry.route.onPopInvoked(true):通知路由pop操作被调用。
  • entry.pop<T>(result):直接调用pop。
  • _afterNavigation(entry.route):导航完成后回调。
相关推荐
最笨的羊羊1 个月前
Flink CDC系列之:学习理解核心概念——Route
route·flink cdc系列·学习理解核心概念
放羊的牧码1 个月前
Git - 如何删除 push 过一次的文件链路追踪?
git·github·idea·push·.gitignore·commit·1024程序员节
拾漓1 个月前
【github小问题】——push后报错error: src refspec master does not match any
github·push·1024程序员节
XMYX-02 个月前
Linux 中的 route 命令介绍以及使用
linux·运维·服务器·route
Commas.KM3 个月前
【vue3|第25期】Vue3中的useRoute:轻松访问路由信息
前端·javascript·vue.js·路由器·路由·route·vue router
LLINELL5 个月前
[SWPUCTF 2022 新生赛]ez_1zpop(php反序列化之pop链构造)
pop
小源同学r7 个月前
Vue3 中 createWebHistory 和 createWebHashHistory 的区别
vue·路由·route
寂夜了无痕8 个月前
mac上添加路由配置
macos·路由·route
威迪斯特9 个月前
Linux系统运维脚本:shell脚本实现查看本机的多种网络信息
linux·网络·脚本·route·grep·awk·ipaddr