在學習怎麼使用AppRoute前,先了解下這幾個問題,肯定這是不是你須要的前端
爲何Redux.js和Vuex是全局Store?git
前端的單頁面應用愈來愈複雜,一個model變化會引發另一個model變化,又可能引發視圖變化。Redux的三大原則,使state的變化可預測成爲可能。其中第一條就是單一數據源,這體現了集中思想。應用維護一顆狀態樹,而數據變化驅動視圖從新刷新。單一的狀態樹更方便數據的管理,因爲生命週期和App一致,組件間數據也更方便傳遞分享(如登陸信息)。github
爲何Fish Redux不是這樣的?json
Fish Redux一開始只支持Page級別Stroe是業務的客觀訴求。Flutter做爲一個新技術棧要用在一個上億用戶的閒魚App中,須要風險控制和隔離,只能先改寫一些頁面,驗證改進迭代再逐步替換。redux
我是否須要使用AppRoute?數組
若是你的訴求和閒魚同樣,那選擇的是高難度路線,須要在集中和分治間作長久鬥爭。建議使用HybridRoute能省點時間,也方便後續改造。否則,那就用AppRoute吧,充分享受Flutter和Redux帶來的優越性。markdown
做者添加了Route這一層,它的核心做用是產生一個Page,對應不一樣場景,實現了三個具體的XXXRouteapp
/// Route 抽象類,只提供返回一個page的能力
abstract class AbstractRoutes {
Widget buildPage(String path, dynamic arguments);
}
/// AppRoutes實現多page公用一個store,適合全新App使用
class AppRoutes<T> implements AbstractRoutes {
final Map<String, Dependent<T>> pages;
final PageStore<T> _store;
...
}
/// 一個page,一個store,適合部分頁面改寫flutter的App使用,如如今的閒魚
class PageRoutes implements AbstractRoutes {
final Map<String, Page<Object, dynamic>> pages;
...
}
/// 混合Routes,能夠同時使用AppRoutes和PageRoutes,適合都要的App,如將來一段時間的閒魚
class HybridRoutes implements AbstractRoutes {
final List<AbstractRoutes> routes;
...
}
複製代碼
定義一個AppRoute框架
/// app_route.dart
/// 由於是全局的,這裏用單例,也比較方便調用
class AppRoute {
static AbstractRoutes _global;
static AbstractRoutes get global {
if (_global == null) {
_global = AppRoutes(preloadedState: AppState.initialState(), pages: {
// 這裏有兩種寫法,效果是同樣的,帶操做符的寫法比較生動,也簡短些。
// RoutePath.todoList: TodoListPage().asDependent(TodoListConn()),
RoutePath.todoList: TodoListConn() + TodoListPage(),
RoutePath.todoDetail: TodoDetailConn() + TodoDetailPage(),
});
}
return _global;
}
}
/// 減小魔法字段,這些常量放在constant裏也能夠,放在這裏只是方便。
class RoutePath {
static const String todoList = 'todo_list';
static const String todoDetail = 'todo_detail';
}
複製代碼
定義一個AppState,用來做爲狀態樹的根節點ide
/// screens/todo_list/state.dart
class AppState implements Cloneable<AppState> {
TodoListState todoListState;
TodoDetailState todoDetailState;
AppState(this.todoListState, this.todoDetailState);
@override
AppState clone() {
return AppState(todoListState, todoDetailState);
}
AppState.initialState()
: todoListState = initState(null),
todoDetailState = TodoDetailState();
}
複製代碼
定義Connect,描述subState和父State之間的轉化關係
/// screens/todo_list/state.dart
/// get定義從大state取小state,set定義小state怎麼改變大state
class TodoListConn extends ConnOp<AppState, TodoListState> {
@override
TodoListState get(AppState state) => state.todoListState;
@override
void set(AppState state, TodoListState subState) =>
state.todoListState = subState;
}
複製代碼
替換原來Page產生的方式
/// main.dart
home: AppRoute.global.buildPage(RoutePath.todoList, null),
複製代碼
額外處理(有數據跳轉的Page)
/// screens/todo_detail/reducer.dart
/// 頁面跳轉可能會有數據傳遞,好比list到detail頁面,須要傳遞id,
/// 這是很常見的,那數據何時傳遞?天然是page生成的時候,能夠看到[AbstractRoutes]
/// 的buildPage接受一個arguments參數,dynamic你能夠傳任意結構數據,推薦傳Map,原生json樣式
/// 若是arguments不爲null,Route會幫咱們發一個route的Action,
/// 因此咱們須要在對應的Reducer裏處理一下
Reducer<TodoDetailState> buildReducer() {
return asReducer<TodoDetailState>(<Object, Reducer<TodoDetailState>>{
RouteAction.route: _route,
...
});
}
/// 接到route Action,更新下state的id
TodoDetailState _route(TodoDetailState state, Action action) {
final TodoDetailState newState = state.clone();
newState.id = action.payload['id'];
return newState;
}
複製代碼
一直以來Fish Redux和Flutter Redux的最佳實踐並不一樣,一個是Page級別的狀態管理,一個是App級別狀態管理,因此算是錯位競品。在Fish Redux加入Route後,它也算徹底體了,這兩個都用事後我簡單對比下:
方便度
Flutter Redux調用簡單,想要深刻理解API含義,會難一些。Fish Redux概念多,感受是把二維數組flat了,大堆的定義和概念,可能會勸退小部份沒耐心的同窗。然而框架意圖是清晰的,並且代碼也有精心設計的痕跡。這點對我而言勢均力敵。
文檔例子
Flutter Redux優勝,文檔和例子都比剛開源的Fish Redux多不少,Fish Redux文檔很少但都有中文版哦
問題響應
Fish Redux優勝,Github上Issue基本能在12小時內獲得做者或熱心網友的回覆和解答。而Flutter Redux的做者維護了不少個庫,精力有限,因此Issue處理速度能夠說是拖拖拉拉了
完備度
功能上都是完備的,形式上Flutter Redux須要依賴兩個庫,Fish Redux沒有任何其餘三方依賴會好一點點
性能
其實狀態管理的初衷並不會很在乎性能,畢竟它只是個狀態管理啊,管理都須要額外成本的。可是fish redux確實關注了並對於大列表場景作了比較突出的優化,性能提高剛剛的。
總結:Fish Redux徹底能夠成爲Flutter狀態管理的備選方案了,並且它還正以肉眼可見的速度在成長。
對比事後以爲Fish Redux不錯,想推銷給長官
我:報告老闆,ali的Fish Redux老NB了,咱們項目要不用這個吧?
老闆:哪NB了?
我:巴拉巴拉~
老闆:哪些大廠在用了
我:額,貌似就ali
老闆:單元測試覆蓋多少?
我:快50%吧
老闆:性能提高多少,有benchmark嗎?
我:。。。
抱歉,以上是我腦補的,但以我老闆的專業度,這些問題必問。。。
本文源碼地址:https://github.com/hyjfine/flutter_redux_sample/tree/fish-redux-route
(完)
@子路宇, 本文版權屬於再惠研發團隊,歡迎轉載,轉載請保留出處。