鑑於Flutter高性能渲染和跨平臺的優點,閃點清單在移動端APP上,使用了完整的Flutter框架來開發。既然是完整APP,架構搭建徹底不受歷史Native APP的影響,沒有歷史包袱的沉澱,設計也能更靈活和健壯。前端
首先列舉部分閃點清單的業務特性(較爲通用的業務特性):android
這幾個業務點,設計到的技術選型有:本地數據庫、前端狀態管理,對不少業務來講,這幾點都是比較核心的東西,也是咱們今天重點要講的內容。git
數據庫選型,首先要定的,就是選擇數據庫類型:關係型數據庫、非關係型數據庫仍是Key/Value存儲。github
對於關係型數據庫,可選的有好比:SQLite、Core Data、GreenDao等;對於非關係型數據庫,可選有Realm、UnQLite等;對於Key/Value存儲,有好比Redis、Berkeley DB、Level DB等。sql
因爲業務形態具備複雜的查詢場景,因此首先排除了Key/Value存儲;而後鑑於業務迭代頻繁,數據結構變更較大,因此徹底的關係型數據庫使用成本會較高,版本更新時在數據兼容和數據清洗方面要作較多的工做;因此咱們採用了NoSQL數據庫,或者支持JSON類型的關係型數據庫。數據庫
Flutter目前在NoSQL上的可選項並很少,Realm、UnQLite等均未支持(固然能夠經過Flutter FFI來封裝給Dart用,但成本太高);Flutter的sqflite插件能夠較好地支持SQLite,但因爲SQLite在3.9之後才支持JSON數據,考慮到Android版本(Android各版本使用的SQLite版本文檔)兼容問題,咱們並無採用sqflite;咱們最終採用的數據庫是Sembast,一個還比較小衆,但性能和API建設都還不錯的NoSQL數據庫。redux
Sembast介紹服務器
Sembast API很簡潔,但能支持較複雜的數據庫操做。 在數據查詢上,可以經過簡單的邏輯API,經過聚合構造出複雜的邏輯查詢語句;數據排序實現也比較完整,支持多字段排序(但不支持bool類型排序);對事務操做也有支持;支持整型自增key。數據結構
Sembast部分API預覽架構
var store = intMapStoreFactory.store('animals');
// 事務處理
await db.transaction((txn) async {
await store.add(txn, {'name': 'fish'});
await store.add(txn, {'name': 'cat'});
await store.add(txn, {'name': 'dog'});
});
// 數據查詢
var finder = Finder(
filter: Filter.greaterThan('name', 'cat'),
sortOrders: [SortOrder('name')]);
var records = await store.find(db, finder: finder);
expect(records.length, 2);
expect(records[0]['name'], 'dog');
expect(records[1]['name'], 'fish');
複製代碼
但因爲對小衆數據庫前途的擔心考慮,咱們設計了便於遷移的數據架構,對數據操做層作了一層抽象,後期若是遷移數據庫,業務層能夠徹底不須要改動。
狀態管理,在現在的前端技術中,是很是重要的一環,好的狀態管理框架,可讓業務更好得解耦、簡化組件數據通信成本、大幅提高開發體驗。咱們在狀態管理選型上花了較多的時間來對比各類方案,好比:provider、bloc、redux、scoped_model、mobx、甚至業界網紅團隊的fish-redux。咱們最終採用的是mobx,關於各個方案的對比,一篇文章講不完,咱們最終選擇mobx,更可能是由於它的API更友好。
Mobx採用註解的方式來定義狀態,並封裝了一個Widget用於Widget的數據更新,學習、使用成本較低。
Mobx的註解使用方式,與Web中的Vue很是相似如:
示例代碼:
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter; abstract class CounterBase with Store {
@observable
int value = 0;
@computed
int get allowCount {
return value*2;
}
@action
void increment() {
value++;
}
}
複製代碼
使用Mobx必須的一個步驟,就是前置編譯步驟。咱們編寫Mobx的狀態腳本,須要在前置編譯環節,編譯成dart可讀的腳本,爲此咱們須要執行flutter pub run build_runner build
生成.g.dart
爲後綴的文件(其實就是將註解轉義爲getter和setter)。 UI更新方式
須要使用Mobx的Widget,使用Observer包裝一層,這樣其就能夠相應Mobx的狀態變化,如:
Observer(
builder: (context) => Text('暱稱: ${userStore.user.username}'),
)
複製代碼
Dart在編譯時和運行時均沒法支持註解,因此Mobx使用了前置編譯腳本解析註解動態生成Dart代碼的方式(Dart官方支持)。Mobx註解方式使用前,須要爲項目添加build_runner
和mobx_codegen
依賴。build_runner爲Dart官方提供,用於在構建項目以前執行特定任務,任務配置於依賴庫的build.yaml
腳本中; mobx_codegen
依賴於該build_runner
將註解生成可執行的Dart代碼(如添加getter和setter方法)。
狀態管理和數據庫,是前端項目基礎框架的重要環節,設計好了能夠很好地提高開發體驗和效率,下降後續開發維護成本。
講到這裏,還並無完成基礎框架的搭建,後面咱們會講解更多的Flutter架構設計內容,好比:國際化、通知、分享、UI設計等等。
持續分享閃點清單在Flutter上的開發經驗,閃點清單移動端APP體驗:
閃點清單PC端APP: 業界惟一一款懸浮清單軟件
閃點清單移動端APP: