关于Flutter for web的导航
通常对于传统网站来说访问行为是让一个HTML地址对应一个页面资源,而对于APP来说内部的多个页面是通过代码指令耦合的,整个APP实际上是一个资源。随着应用规模的扩大原本通过指令进行页面跳转的模式被抽取归纳统一为路由跳转。随着HYBRID的发展与urlscheme结合为协议路由统一跳转与状态传递的方式。
flutter中的页面导航使用'router'进行,在应用内部导航的方式比较自由,指令或者命名或者根据已有规范统一到urlScheme中走中心路由的架构都可以随自己应用的体量来选择。
拦截URL
使用 onGenerateRoute: onGenerateRoute可以截获通过URL获取路由的路径,在flutter for web中这里就可以截获在浏览器地址中输入的链接中index地址后面的部分
imagevoid main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "main",
debugShowCheckedModeBanner: false,
onGenerateRoute: onGenerateRoute,
);
}
}
Route<dynamic> onGenerateRoute(RouteSettings settings) {
String routeName = settings.name;
//根据地址跳转不同的页面
if (routeName.contains('/artical')) {
//截取参数
String arg = "";
if(routeName.length > 10){
arg = routeName.substring(9,routeName.length);
}
return MaterialPageRoute(builder: (context) { return HomeWidget(arguments: arg,); });
} else if (routeName.contains('/tool')) {
return MaterialPageRoute(builder: (context) { return ToolsPage(); });
}else if (routeName.contains('/quote')) {
return MaterialPageRoute(builder: (context) { return KlinePage(); });
}else{
return MaterialPageRoute(builder: (context) { return HomeWidget(); });
}
}
HashTag("#")问题
由于Flutter for web 是作为HTMLApp的形式存在因此对于浏览器来说,无论进行多少次内部跳转仍然在一个页面内。
nginx以#为分界解析路径。flutter通过hashtag判别获取url路径给onGenerateRoute进行拦截获取参数。对于单页面或者内嵌WEBAPP来说这对访问不会造成任何影响。但如果要通过URL访问指定的页面会在一些情况下无法访问。
隐藏自动添加的"/#/"
如果只需要通过根路径访问网站。此时flutter会自动将"/#/"拼接在地址栏中
image如果希望去除# 有两种方法
1.阻止自动添加#
可以从从项目中删除向地址栏添加#的代码 。
首先build项目,然后找到构建的项目的 main.dart.js文件并打开搜索 '#'+a找到
we:function(a){return a.length===0?H.b(window.location.pathname)+H.b(window.location.search):"#"+a},
删除 "#"+。
image2.向浏览器添加一个新的URL
html.window.history.pushState(null, "flutter", "/");
配合NGINX重定向使用URL导航
如果需要使用URL通过浏览器在flutter web app内导航则需要使用hashTag的机制向APP传递地址信息,此时若想要在导航链路中排除"#",需要配合地址重定向和html.window.history.pushState来手动构建导航体系。
-
通过NGINX添加重定向
image -
获取路径后Push访问路经
image
如果是访问有连接后缀的地址onGenerateRoute 会被调用两次,第一次是传入空置进去,第二次才会传入地址栏中的地址。因此在没有收到后缀的地址中不能pushstate否则会屏蔽掉后续的重定向内容导致链接跳转失效。
过程大致如图
image在这个方案下,页面导航与Nginx地址解析实际上是深度绑定了NGINX需要重定向所有应用中PUSHSTATE进浏览器的地址。而如果使用了CDN加速 会导致重定向失效
通过浏览器获取URL进行导航
在无法通过NGINX重定向来协助导航的情况下,只能根据浏览器这一使用场景做特殊处理。让实例自己获取当前URL去做导航。使用html.window.location获取当前访问的地址。而NGINX只需要将所有有导航目的地的路径都指向根目录就行了。
NGINX:
imageFlutter:
image最后 如果设置了一些特殊的NGINX规则如二级路径有可能导致flutter中无法找到图片资源。因此建议使用远端资源。
网友评论