關(guān)于Flutter for web的導(dǎo)航
通常對于傳統(tǒng)網(wǎng)站來說訪問行為是讓一個HTML地址對應(yīng)一個頁面資源维蒙,而對于APP來說內(nèi)部的多個頁面是通過代碼指令耦合的异希,整個APP實際上是一個資源。隨著應(yīng)用規(guī)模的擴大原本通過指令進行頁面跳轉(zhuǎn)的模式被抽取歸納統(tǒng)一為路由跳轉(zhuǎn)敛惊。隨著HYBRID的發(fā)展與urlscheme結(jié)合為協(xié)議路由統(tǒng)一跳轉(zhuǎn)與狀態(tài)傳遞的方式膊毁。
flutter中的頁面導(dǎo)航使用'router'進行胀莹,在應(yīng)用內(nèi)部導(dǎo)航的方式比較自由,指令或者命名或者根據(jù)已有規(guī)范統(tǒng)一到urlScheme中走中心路由的架構(gòu)都可以隨自己應(yīng)用的體量來選擇婚温。
攔截URL
使用 onGenerateRoute: onGenerateRoute可以截獲通過URL獲取路由的路徑描焰,在flutter for web中這里就可以截獲在瀏覽器地址中輸入的鏈接中index地址后面的部分
void 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;
//根據(jù)地址跳轉(zhuǎn)不同的頁面
if (routeName.contains('/artical')) {
//截取參數(shù)
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的形式存在因此對于瀏覽器來說,無論進行多少次內(nèi)部跳轉(zhuǎn)仍然在一個頁面內(nèi)栅螟。
nginx以#為分界解析路徑荆秦。flutter通過hashtag判別獲取url路徑給onGenerateRoute進行攔截獲取參數(shù)。對于單頁面或者內(nèi)嵌WEBAPP來說這對訪問不會造成任何影響力图。但如果要通過URL訪問指定的頁面會在一些情況下無法訪問步绸。
隱藏自動添加的"/#/"
如果只需要通過根路徑訪問網(wǎng)站。此時flutter會自動將"/#/"拼接在地址欄中
如果希望去除# 有兩種方法
1.阻止自動添加#
可以從從項目中刪除向地址欄添加#的代碼 吃媒。
首先build項目瓤介,然后找到構(gòu)建的項目的 main.dart.js文件并打開搜索 '#'+a找到
we:function(a){return a.length===0?H.b(window.location.pathname)+H.b(window.location.search):"#"+a},
刪除 "#"+。
2.向瀏覽器添加一個新的URL
html.window.history.pushState(null, "flutter", "/");
配合NGINX重定向使用URL導(dǎo)航
如果需要使用URL通過瀏覽器在flutter web app內(nèi)導(dǎo)航則需要使用hashTag的機制向APP傳遞地址信息赘那,此時若想要在導(dǎo)航鏈路中排除"#"惑朦,需要配合地址重定向和html.window.history.pushState來手動構(gòu)建導(dǎo)航體系。
-
通過NGINX添加重定向
image -
獲取路徑后Push訪問路經(jīng)
image
如果是訪問有連接后綴的地址onGenerateRoute 會被調(diào)用兩次漓概,第一次是傳入空置進去漾月,第二次才會傳入地址欄中的地址。因此在沒有收到后綴的地址中不能pushstate否則會屏蔽掉后續(xù)的重定向內(nèi)容導(dǎo)致鏈接跳轉(zhuǎn)失效胃珍。
過程大致如圖
在這個方案下梁肿,頁面導(dǎo)航與Nginx地址解析實際上是深度綁定了NGINX需要重定向所有應(yīng)用中PUSHSTATE進瀏覽器的地址蜓陌。而如果使用了CDN加速 會導(dǎo)致重定向失效
通過瀏覽器獲取URL進行導(dǎo)航
在無法通過NGINX重定向來協(xié)助導(dǎo)航的情況下,只能根據(jù)瀏覽器這一使用場景做特殊處理吩蔑。讓實例自己獲取當前URL去做導(dǎo)航钮热。使用html.window.location獲取當前訪問的地址。而NGINX只需要將所有有導(dǎo)航目的地的路徑都指向根目錄就行了烛芬。
NGINX:
Flutter:
最后 如果設(shè)置了一些特殊的NGINX規(guī)則如二級路徑有可能導(dǎo)致flutter中無法找到圖片資源隧期。因此建議使用遠端資源。