Mobx在Flutter中的使用教程

追著夢想的兔發表於2019-10-25

如果在開發中遇到什麼問題,歡迎加入 flutter興趣交流群 QQ群:541020533

前言

Flutter 用的是 Dart 語言,而 Dart 很多地方借鑑了 React ,比如說每次頁面重新整理用的是和 React 類似的setState寫法,這樣雖然便於頁面資料的更新,但也帶來了 React 中一直存在的 state無法跨頁面更新的問題。

React 提供了 Redux , Mobx 等框架來管理頁面狀態和 App 全域性狀態,而閒魚也提供了基於 Redux 的 Fish Redux 用來管理資料的組裝式 Flutter 應用框架。

本文主要講的mobx.dart是 Mobx 官方推出的,基於 Dart 語言,用來處理 Dart 和 Flutter 狀態的框架。 思路和 Mobx 在 JS 中的用法差不多。作者在開發 React-Native 時用的最多的就是 Mobx, 最近正好在使用 Flutter 重寫開源專案 識兔,所以本文就應運而生。

需求

本文主旨 使用 ,而使用最好的辦法就是實現一個功能。

本文實現一個很簡單的關於跨頁面傳值的功能。

建立三個tab,在第一個tab,做一個模糊的背景圖,在第三個tab,點選按鈕,將第一個tab的背景圖換掉。

Mobx在Flutter中的使用教程

準備工作

dependencies:
  mobx: 0.3.8+1 
  flutter_mobx: 0.3.3+1
  
  mobx_codegen: 0.3.9+1 // MobX程式碼生成庫,用來生成 .g.dart的庫
  
  provider: 3.1.0+1  // 全域性狀態管理
複製程式碼

建立Store

為什麼建立Store呢? 因為我們要做的是跨頁面修改狀態,在 Redux 中稱為 Store, 這裡直接借鑑過來。

App可以有多個 Store, 但不推薦每個頁面都是 Store,推薦只有那種需要跨頁面修改狀態的頁面命名為 xxxStore,其他都可以成為 xxxMobx。

shitu_store.dart

import 'package:mobx/mobx.dart'; // 引入

part 'shitu_store.g.dart'; // 稍後會用命令列生成這個檔案,但這裡必須要這麼寫

class ShiTuStore = _ShiTuStore with _$ShiTuStore; // 固定寫法

abstract class _ShiTuStore with Store {

  // 預設圖片地址
  @observable
  String imageUrl =
      'http://ww1.sinaimg.cn/large/0065oQSqly1g2pquqlp0nj30n00yiq8u.jpg';

  // 外部呼叫,用來修改預設圖片的方法
  @action
  setImageUrl(String url) {
    imageUrl = url;
  }
}
複製程式碼

執行命令列

flutter packages pub run build_runner build
複製程式碼

上面寫到了要新增part 'shitu_store.g.dart'; 這裡通過這個命令列自動生成該檔案。 通過上面這行命令,會讓 Dart 新增對 @observable@computed@action的支援,讓 Mobx 的使用變得簡單。

這部分程式碼,因為是自動生成的,這裡就不貼出來了。需要的可以看開源專案 flutter_shitu

繫結至Provider

這步主要做的是對入口檔案main.dart的修改,需要引入providershitu_store;

 @override
  Widget build(BuildContext context) => MultiProvider(
    providers: [            // 陣列,可以注入多個Store
      Provider<ShiTuStore>( // 需要更新的Store
            builder: (_) => ShiTuStore(),
        ),
    ],
    child: MaterialApp(
        theme: ThemeData(backgroundColor: Colors.white),
        home: Scaffold(
            resizeToAvoidBottomPadding: false,
            body: Launch(),
        ),
    ),
);
複製程式碼

業務程式碼

前期準備工作都完成了,接下來就是修改頁面效果了。 這裡先把最重要的程式碼貼出來,最重要,最重要,最重要!

ShiTuStore store = Provider.of<ShiTuStore>(context);
複製程式碼

看到上面的程式碼,有沒有什麼想法? 通過上面的程式碼,就可以在頁面中拿到 Store 中的資料了!

這裡貼出部分程式碼,全部程式碼可以在專案中檢視flutter_shitu

shitu.dart

body: Stack(
    alignment: Alignment.centerLeft,
    children: <Widget>[
        Image.network(
            store.imageUrl, // 通過store得到要展示的圖片
            fit: BoxFit.fitHeight,
            height: height,
        ),
        BackdropFilter(
            filter: ImageFilter.blur(
                sigmaX: 5,
                sigmaY: 5,
            ),
            child: Container(
                color: Colors.white.withOpacity(0.1),
            ),
        ),
    ],
)
複製程式碼

可以發現我這裡用了 Stack 元件,但為什麼用這個? 有興趣的小夥伴可以看我另一個系列的文章 從0到1使用Flutter重構識兔(1)

mine.dart

@override
  Widget build(BuildContext context) {
    final store = Provider.of<ShiTuStore>(context);
    
    return MaterialApp(
      home: Scaffold(
          appBar: AppBar(title: Text('我的')),
          body: Container(
            alignment: Alignment.center,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  child: Text('點選更改'),
                  onPressed: () {
                  
                    // 點選時,呼叫store中的方法切換首頁圖片
                    
                    store.setImageUrl(
                        'https://ws1.sinaimg.cn/large/0065oQSqly1g0ajj4h6ndj30sg11xdmj.jpg');
                  },
                )
              ],
            ),
          ),
        ),
    );
  }
複製程式碼

總結

主要流程就是 Store => 生成Mobx配置 => Provider => 頁面。

最近在用 Flutter 重寫 識兔專案

Flutter版識兔也已經開源,稍後會有更多新文章和新功能向大家展示,歡迎star,fork。

從0到1使用Flutter重構識兔系列文章:

從0到1使用Flutter重構識兔(1)

如果在開發中遇到什麼問題,歡迎加入 flutter興趣交流群 QQ群:541020533

相關文章