fish_redux使用詳解---看完就會用!
阿新 • • 發佈:2020-10-21
**說句心裡話,這篇文章,來來回回修改了很多次,如果認真看完這篇文章,還不會寫fish_redux,請在評論裡噴我。**
## 前言
來學學難搞的fish_redux框架吧,這個框架,官方的文件真是一言難盡,比flutter_bloc官網的文件真是遜色太多了,但是一旦知道怎麼寫,頁面堆起來也是非常爽呀,結構分明,邏輯也會錯落有致。
其實在當時搞懂這個框架的時候,就一直想寫一篇文章記錄下,但是因為忙(lan),導致一直沒寫,現在覺得還是必須把使用的過程記錄下,畢竟剛上手這個框架是個蛋痛的過程,必須要把這個過程做個記錄。
這不僅僅是記錄的文章,文中所給出的示例,也是我重新構思去寫的,過程也是力求闡述清楚且詳細。
![img](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808161402.jpg)
### 幾個問題點
- 頁面切換的轉場動畫
- 頁面怎麼更新資料
- fish_redux各個模組之間,怎麼傳遞資料
- 頁面跳轉傳值,及其接受下個頁面回傳的值
- 怎麼配合ListView使用
- ListView怎麼使用adapter,資料怎麼和item繫結
- 怎麼將Page當做widget使用(BottomNavigationBar,NavigationRail等等導航欄控制元件會使用到)
- 這個直接使用:XxxPage.buildPage(null) 即可
如果你在使用fish_redux的過程中遇到過上述的問題,那就來看看這篇文章吧!這裡,會解答上面所有的問題點!
## 準備
### 引入
**fish_redux相關地址**
- GitHub地址:[https://github.com/alibaba/fish-redux](https://github.com/alibaba/fish-redux)
- Pub地址:[https://pub.dev/packages/fish_redux](https://pub.dev/packages/fish_redux)
我用的是0.3.X的版本,算是第三版,相對於前幾版,改動較大
- 引入fish_redux外掛,想用最新版外掛,可進入pub地址裡面檢視
```
fish_redux: ^0.3.4
#演示列表需要用到的庫
dio: ^3.0.9 #網路請求框架
json_annotation: ^2.4.0 #json序列化和反序列化用的
```
### 開發外掛
- 此處我們需要安裝程式碼生成外掛,可以幫我們生成大量檔案和模板程式碼
- 在Android Studio裡面搜尋”fish“就能搜出外掛了,外掛名叫:FishReduxTemplate
![image-20200808181112391](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233038.png)
- BakerJQ編寫:[Android Studio的Fish Redux模板](https://github.com/BakerJQ/FishReduxTemplateForAS)。
- huangjianke編寫:[VSCode的Fish Redux模板](https://github.com/huangjianke/fish-redux-template)
### 建立
- 這裡我在新建的count資料夾上,選擇新建檔案,選擇:New ---> FishReduxTemplate
![image-20200808181242775](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233050.png)
- 此處選擇:Page,底下的“Select Fils”全部選擇,這是標準的redux檔案結構;這邊命名建議使用大駝峰:Count
- Component:這個一般是可複用的相關的元件;列表的item,也可以選擇這個
- Adapter:這裡有三個Adapter,都可以不用了;fish_redux第三版推出了功能更強大的adapter,更加靈活的繫結方式
![image-20200808181325258](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233056.png)
- 建立成功後,記得在建立的資料夾上右擊,選擇:Reload From Disk;把建立的檔案刷新出來
![image-20200808181410600](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233101.png)
- 建立成功的檔案結構
- page:總頁面,註冊effect,reducer,component,adapter的功能,相關的配置都在此頁面操作
- state:這地方就是我們存放子模組變數的地方;初始化變數和接受上個頁面引數,也在此處,是個很重要的模組
- view:主要是我們寫頁面的模組
- action:這是一個非常重要的模組,所有的事件都在此處定義和中轉
- effect:相關的業務邏輯,網路請求等等的“副作用”操作,都可以寫在該模組
- reducer:該模組主要是用來更新資料的,也可以寫一些簡單的邏輯或者和資料有關的邏輯操作
![image-20200808181550186](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233107.png)
- OK,至此就把所有的準備工作搞定了,下面可以開搞程式碼了
![img](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233113.jpg)
## 開發流程
### redux流程
- 下圖是阮一峰老師部落格上放的redux流程圖
![img](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233125.jpeg)
### fish_redux流程
- 在寫程式碼前,先看寫下流程圖,這圖是憑著自己的理解畫的
- 可以發現,事件的傳遞,都是通過dispatch這個方法,而且action這層很明顯是非常關鍵的一層,事件的傳遞,都是在該層定義和中轉的
- 這圖在語雀上調了半天,就在上面加了個自己的github水印地址
![fish_redux流程](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233137.jpg)
- 通過倆個流程圖對比,其中還是有一些差別的
- redux裡面的store是全域性的。fish_redux裡面也有這個全域性store的概念,放在子模組裡面理解store,react;對應fish_redux裡的就是:state,view
- fish_redux裡面多了effect層:這層主要是處理邏輯,和相關網路請求之類
- reducer裡面,理論上也是可以處理一些和資料相關,簡單的邏輯;但是複雜的,會產生相應較大的“副作用”的業務邏輯,還是需要在effect中寫
## 範例說明
這邊寫幾個示例,來演示fish_redux的使用
- 計數器
- fish_redux正常情況下的流轉過程
- fish_redux各模組怎麼傳遞資料
- 頁面跳轉
- A ---> B(A跳轉到B,並傳值給B頁面)
- B ---> A(B返回到A,並返回值給A頁面)
- 列表文章
- 列表展示-網路請求
- 列表修改-單item重新整理
- 多樣式列表
- 列表存在的問題+解決方案
- 全域性模組
- 全域性切換主題
- 全域性模式優化
- 大幅度提升開發體驗
- Component使用
- page中使用component
- 廣播
- 開發小技巧
- 弱化reducer
- widget組合式開發
## 計數器
### 效果圖
![fish_redux中count](https://cdn.jsdelivr.net/gh/CNAD666/MyData/pic/flutter/bookWeb/20200808233256.gif)
- 這個例子演示,view中點選此操作,然後更新頁面資料;下述的流程,在effect中把資料處理好,通過action中轉傳遞給reducer更新資料
- view ---> action ---> effect ---> reducer(更新資料)
- 注意:該流程將展示,怎麼將資料在各流程中互相傳遞
### 標準模式
- main
- 這地方需要注意,cupertino,material這類系統包和fish_redux裡包含的“Page”類名重複了,需要在這類系統包上使用hide,隱藏系統包裡的Page類
- 關於頁面的切換風格,可以在MaterialApp中的onGenerateRoute方法中,使用相應頁面切換風格,這邊使用ios的頁面切換風格:cupertino
```dart
///需要使用hide隱藏Page
import 'package:flutter/cupertino.dart'hide Page;
import 'package:flutter/material.dart' hide Page;
void main() {
runApp(MyApp());
}
Widget createApp() {
///定義路由
final AbstractRoutes routes = PageRoutes(
pages: >{
"CountPage": CountPage(),
},
);
return MaterialApp(
title: 'FishDemo',
home: routes.buildPage("CountPage", null), //作為預設頁面
onGenerateRoute: (RouteSettings settings) {
//ios頁面切換風格
return CupertinoPageRoute(builder: (BuildContext context) {
return routes.buildPage(settings.name, settings.arguments);
})
// Material頁面切換風格
// return MaterialPageRoute