我搜索了很多有关“使用命名路线在屏幕之间导航的好处是什么”的信息。我找不到任何实际的好处,实际上它有很多缺点并且令人讨厌。
1. flutter文档中说命名路由是为了避免代码重复。
例如,如果我想使用 String 一个参数导航到 SecondRoute,它会从此更改
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute('Some text')),
);
Run Code Online (Sandbox Code Playgroud)
对此
Navigator.pushNamed(context, SecondRoute.routeName, arguments: 'Some text');
Run Code Online (Sandbox Code Playgroud)
我需要在主文件中注册它
MaterialApp(
onGenerateRoute: (settings) {
if (settings.name == SecondRoute.routeName) {
final String text = settings.arguments as String;
return MaterialPageRoute(
builder: (context) => SecondRoute(text),
);
}
},
);
Run Code Online (Sandbox Code Playgroud)
如果我有更多路线,我需要为每个路线处理和分配参数。这不是更多的重复和复杂性吗?
还setting.arguments
没有类型,那不是很糟糕吗?
2. 使用时无法选择使用哪个构造函数pushNamed
。
例如,我有两个构造函数default
和otherConstructor
class SecondRoute extends StatelessWidget {
static const String routeName = '/second';
String? text;
SecondRoute(this.text);
SecondRoute.otherConstructor(String text) {
this.text = 'Other Constructor: ' + text;
}
}
Run Code Online (Sandbox Code Playgroud)
我如何知道pushNamed
我想使用哪一个。
我有一个想法将构造函数名称作为参数传递并像这样检查它
Navigator.pushNamed(context, SecondRoute.routeName, arguments: ['default' or 'otherConstructor','Some text']);
Run Code Online (Sandbox Code Playgroud)
在主文件中
MaterialApp(
onGenerateRoute: (settings) {
if (settings.name == SecondRoute.routeName) {
final args = settings.arguments as List<String>;
if (args[0] == 'otherConstructor') {
return MaterialPageRoute(
builder: (context) => SecondRoute.otherConstructor(text),
);
} else if (args[0] == 'default') {
return MaterialPageRoute(
builder: (context) => SecondRoute(text),
);
}
}
},
);
Run Code Online (Sandbox Code Playgroud)
但这非常非常复杂,显然不是一个好方法。
3. reddit 和 stackoverflow 中的一些 anwsers 说命名路由通过将每个路由保留在主文件中使代码更加集中。
集中化当然是好的,但为什么不采取其他方式呢?
例如,将所有包含路由的 dart 文件保留在新文件夹中
有人可以告诉我为什么大多数人使用命名路线吗?谢谢你的帮助。
从我的角度来看,我个人认为您担心的根本原因是您继续使用构造函数或注入在屏幕上传递数据。
参考flutter官方文档:https://docs.flutter.dev/development/data-and-backend/state-mgmt/declarative
我是一名拥有 UI 工具包的 iOS 开发人员,所以我认为你和我有同样的问题,我通过改变我的思维流程解决了这个问题。
重要的事情:从声明式 UI 图片来看:UI = f(state)。
对于您的问题(1):
对于您的问题(2):
对于您的问题(3):
注意:就个人而言,我现在将小部件分为两种类型:屏幕小部件和演示小部件。
最初的想法来自redux的创始人(https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)
=>有了这个想法,它清楚地解决了你的问题(1)和(2)。对于(3),通过拆分到另一个文件夹并导入,它应该以主文件中的一些行结束,如下所示(屏幕上没有任何进程参数更改):
为了利益:
我个人认为最大的优点是:
1 - 您可以稍后更改屏幕而无需修改工作代码(开闭原则):假设您的客户想要将屏幕 A 更改为屏幕 A',其中在您的代码中有很多导航。
示例:您的应用程序可以从 3 种不同的逻辑进入登录屏幕:从启动画面、从按注销、从管理员禁止消息。
如果您使用:MaterialPageRoute(builder: (context) => SecondRoute('Some text')),那么您需要在完美运行的代码中多次替换它(示例中为3次)。最危险的是:也许“来自管理员禁止消息”的逻辑是来自其他开发者的@@
如果您使用:Navigator.pushNamed(context,SecondRoute.routeName,arguments:'Some text'),您可以通过将其重定向到另一个屏幕(新的登录屏幕)来更改拆分文件夹中的代码(您在(3)中提到的)
下面的事情我认为不太重要:
2-(仅注意)如果您使用网页版本构建项目,您将在url地址中包含路由名称,因此它会打开您的页面以获取url。
3-防止大量不必要的导入(例如您可以在登录中看到,如果您使用路由,只需导入1个文件。但是您直接使用导航器,您需要导入许多相关屏幕:注册,忘记密码......)。无论如何,它可以通过创建类似 screen_index.dart 的内容来解决。
归档时间: |
|
查看次数: |
4218 次 |
最近记录: |