在项目里使用
- flutter包管理网站 里搜索
fish_redux
- 在项目的
pubspec.yaml
里的dependencies
下添加如:fish_redux: ^0.2.4
- vscode里搜索
fish-redux-template
安装 - 文件夹右键选择
Generate Page Template
,Generate Component Template
,Generate Adapter Template
, 如需要一个页面Widget的话选择:Generate Page Template
fish_redux目录结构
-
state.dart 创建页面状态类,包含标题和内容数据,状态类必须实现Cloneable接口
-
action.dart 表示意图、动作的意思,给view或者effect用的。
-
effect.dart 里头是一些事件,发起异步请求等
- 在
effect
里获取当前widget
的state
, 使用Context<AmapState>类型下的 ctx.state
- 在
-
reducer.dart 用于接收意图,该文件提供了Reducer,声明Reducer监听的action,实现监听到action的动作 (修改值的地方)
-
adapter.dart 它的目标是解决 Component 模型在 ListView 的场景下的问题
-
view.dart 文件提供实现界面的方法
Widget buildView(IndexState state, Dispatch dispatch, ViewService viewService) {
print(prefix0.window.physicalSize);
print(MediaQuery.of(viewService.context).size);
return Scaffold(
appBar: AppBar(
actionsIconTheme: IconThemeData(color: Color.fromRGBO(252, 100, 66, 1.0)),
iconTheme: IconThemeData(color: Color.fromRGBO(252, 100, 66, 1.0)),
backgroundColor: Color.fromRGBO(255, 255, 255, 0.0),
bottom: PreferredSize(// appbar下边的element
preferredSize: Size(650.0, 50.0),
child: Container(
child: Row(
children:
),
),
),
bottomOpacity: 0.5, // appbar下边的字体不透明度
leading: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children:
IconButton(
padding: EdgeInsets.all(0.0),
iconSize: 35,
alignment: Alignment.centerRight,
icon: Icon(Icons.account_circle),
onPressed: () {
print("个人中心开启");
},
),
],
),
),
title: Text(
state.title,
style: TextStyle(color: Color.fromRGBO(72, 72, 72, 1.0)),
),
actions:
IconButton(
padding: EdgeInsets.all(0.0),
iconSize: 35,
alignment: Alignment.centerLeft,
icon: Icon(Icons.headset),
onPressed: () {
print("客服开启");
},
),
],
),
body: viewService.buildComponent("amap"),
floatingActionButton: FloatingActionButton(
onPressed: () {
dispatch(IndexActionCreator.onAction(1));
},
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
- **page.dart** 把view,reducer,view涵盖进来
- **conponent.dart** 把view,reducer,view涵盖进来, **遵循fish_redux的一个页面一个store, `所以component里有的state, page里也一定要有, component里没有自己独立的state` **
## **使用注意点**
1. 需要使用别的页面, 请使用 `IndexPage().buildPage(null)`
2. 需要使用别的组件, 请使用 `viewService.buildComponent("amap")`, **注意**
1. "amap" 是在 `page.dart` 里声明的, 如:
class IndexPage extends Page<IndexState, Map<String, dynamic>> {
IndexPage()
: super(
initState: initState,
effect: buildEffect(),
reducer: buildReducer(),
view: buildView,
dependencies: Dependencies<IndexState>(
adapter: null,
slots: <String, Dependent<IndexState>>{
// 在这里声明需要用到的组件AmapComponent(), 可以传参
"amap": AmapConnector() + AmapComponent()
}),
middleware: <Middleware<IndexState>>[],
);
}
2. 在 `state.dart` 里新增一个 `AmapConnector` 类继承 `Reselect2` 或者 `Reselect1`, 重写下面几个方法, 可以使用 **vscode**里的`修复功能`快速生成需要重写的方法, 如:
class AmapConnector extends Reselect2<IndexState, AmapState, String, int> {
@override
AmapState computed(String sub0, int sub1) {
// TODO: implement computed
return AmapState()
..title = sub0
..count = sub1;
}
@override
String getSub0(IndexState state) {
// TODO: implement getSub0
return state.title;
}
@override
int getSub1(IndexState state) {
// TODO: implement getSub1
return state.count;
}
@override
void set(IndexState state, AmapState subState) {
// TODO: implement set
if (subState.title != null && subState.title != state.title) {
state.title = subState.title;
}
}
}
3. **父(page) -> 子(component) 交互**
- `父page` 获取 `子component` 的方法: 直接调用 `子component` 的 `Action` 来触发
- `父page` 修改 `子component`的state: 直接修改当前 `子component connector的父page的state`就能自动修改子state, 例如:
```
AmapState computed(String sub0, int sub1) {
// **记得return后面添加需要自动修改子state的属性**
return AmapState()
..title = sub0
..count = sub1;
}
```
- `子component` 获取或者调用 `父page` 的state或者方法的话, 直接触发 `父page` 的 `Action` 就可以了, 还可以修改 `子component` 后定义下面的规则, 自动修改绑定好的 `父page` 的值.
- **注意: 子component 要想修改state生效, 必须在定义如: `class AmapConnector extends Reselect`类里面的 `set` 重写方法里赋值给父page, 记得判断非null和这两货需要修改的值不一样 例子在上面. **