本文主要記錄個(gè)人在學(xué)習(xí)fish redux中的component部分,通過編寫一個(gè)登錄框架來加深理解睛挚。
首先在lib下創(chuàng)建login包邪蛔,通過右鍵fish redux Template,創(chuàng)建LoginPage扎狱。
fish redux中的component是用來組成page中view的侧到,所以是不能單獨(dú)使用的,其中的用法在代碼上表現(xiàn)的很直接:
class LoginPage extends Page<LoginState, Map<String, dynamic>> {
LoginPage()
: super(
initState: initState,
effect: buildEffect(),
reducer: buildReducer(),
view: buildView,
dependencies: Dependencies<LoginState>(
adapter: null,
slots: <String, Dependent<LoginState>>{
'smsComponent':
SmsLoginConnector() + SmsComponent(),
'pwdComponent':
PwdLoginConnector() + PwdComponent(),
}),
middleware: <Middleware<LoginState>>[
],);
}
代碼中的slots淤击,依賴于smsComponent及pwdComponent兩個(gè)子組件匠抗,通過連接器將LoginPage與SmsComponent、PwdComponent聯(lián)系起來遭贸。
看到這里戈咳,明白SmsComponent跟PwdComponent是LoginPage的子組件,在login目錄下面壕吹,按照創(chuàng)建LoginPage方式著蛙,創(chuàng)建出來兩個(gè)component——PwdComponent&SmsComponent。至此耳贬,已經(jīng)完成了login界面目錄結(jié)構(gòu)上的搭建踏堡。
然后,開始使用component來組裝頁面(page)了:
第一步咒劲,在LoginState(State文件)中顷蟆,初始化state,loginState是Loginpage的state腐魂,其中應(yīng)該包含子組件的state的初始化及創(chuàng)建聯(lián)系:
class LoginState implements Cloneable<LoginState> {
SmsState smsState;
PwdState pwdState;
bool isSmsModel;
@override
LoginState clone() {
return LoginState()
..smsState = smsState
..pwdState = pwdState
..isSmsModel=isSmsModel;
}
}
LoginState initState(Map<String, dynamic> args) {
return LoginState()..isSmsModel = true
..pwdState = PwdState(loginBtnEnable: false)//初始化pwdComponent中按鍵的狀態(tài)
..smsState = SmsState(loginBtnEnable: false);//初始化smsComponent中按鍵的狀態(tài)
}
//smsComponent與page的連接器
class SmsLoginConnector extends ConnOp<LoginState,SmsState>{
@override
SmsState get(LoginState state) {
return state.smsState;
}
@override
void set(LoginState state, SmsState subState) {
state.smsState = subState;
}
}
//pwdComponent與page的連接器
class PwdLoginConnector extends ConnOp<LoginState,PwdState>{
@override
PwdState get(LoginState state) {
return state.pwdState;
}
@override
void set(LoginState state, PwdState subState) {
state.pwdState = subState;
}
}
第二步帐偎,在view中引用smsComponent及pwdComponent。
通過 state中的isSmsModel來確定引用當(dāng)前那個(gè)子組件:
Widget buildView(LoginState state, Dispatch dispatch, ViewService viewService) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
......
_getLoginView(state,viewService),//引入子組件
],
),
),
);
}
//判斷當(dāng)前的isSmsModel蛔屹,加載不同的組件
Widget _getLoginView(LoginState state,ViewService viewService){
if(!state.isSmsModel){
return Container(
child: viewService.buildComponent('smsComponent'),
);
}else{
return Container(
child: viewService.buildComponent('pwdComponent'),
);
}
}
state.isSmsModel是由頁面頂部的“密碼登錄”跟“驗(yàn)證碼登錄”兩個(gè)按鍵控制的削樊,具體實(shí)現(xiàn)可以參考GitHub中的具體代碼。
第三步,實(shí)現(xiàn)驗(yàn)證碼登錄及密碼登錄的切換
在login的Action中創(chuàng)建pwdLogin漫贞,及smsLogin兩個(gè)意圖甸箱,view中的密碼登錄及驗(yàn)證碼登錄按鍵,觸發(fā)這兩個(gè)意圖迅脐,并發(fā)送(dispatch)給effect芍殖,拿到pwdLogin及smsLogin兩個(gè)意圖的effect將該意圖,再次發(fā)生(dispatch)給reducer谴蔑,然后通過reducer來更新當(dāng)前的state,并更新view豌骏。
......
LoginState _pwdLogin(LoginState state, Action action){
final LoginState newState = state.clone();
newState.isSmsModel = false;
return newState;
}
第四步,完善component
component的state中包含一個(gè)bool類型的狀態(tài)loginBtnEnable隐锭,表示登錄按鈕是否可用肯适。在LoginPage state中默認(rèn)值為false。接下來是component的view:
Widget buildView(PwdState state, Dispatch dispatch, ViewService viewService) {
return Container(
margin: EdgeInsets.only(left: 30, top: 40, right: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: TextField(
decoration: InputDecoration(
hintText: "請輸入手機(jī)號(hào)碼",
hintStyle: TextStyle(color: Colors.grey[300], fontSize: 14),
border: InputBorder.none,
),
cursorColor: Color(0xFF009274),
),
decoration: BoxDecoration(
// 下滑線淺灰色成榜,寬度1像素
border: Border(
bottom: BorderSide(color: Colors.grey[300], width: 0.5))),
),
Stack(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 20),
child: TextField(
decoration: InputDecoration(
hintText: "請輸入驗(yàn)證碼",
hintStyle: TextStyle(color: Colors.grey[300], fontSize: 14),
border: InputBorder.none,
),
obscureText: true,
cursorColor: Color(0xFF009274),
),
decoration: BoxDecoration(
// 下滑線淺灰色框舔,寬度1像素
border: Border(
bottom: BorderSide(color: Colors.grey[300], width: 0.5))),
),
......//詳細(xì)代碼,請參考Github
}
到這里赎婚,我們就完成了多個(gè)component組件組裝一個(gè)page刘绣,以上都是開發(fā)思路,具體實(shí)現(xiàn)可參考https://github.com/zjt19870816/fish_redux_login