真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

FlutterReact編程的方法是什么-創(chuàng)新互聯(lián)

這篇文章主要介紹“Flutter React編程的方法是什么”,在日常操作中,相信很多人在Flutter React編程的方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Flutter React編程的方法是什么”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

專業(yè)從事網(wǎng)站制作、成都網(wǎng)站建設(shè),高端網(wǎng)站制作設(shè)計(jì),成都微信小程序,網(wǎng)站推廣的成都做網(wǎng)站的公司。優(yōu)秀技術(shù)團(tuán)隊(duì)竭力真誠(chéng)服務(wù),采用H5高端網(wǎng)站建設(shè)+CSS3前端渲染技術(shù),成都響應(yīng)式網(wǎng)站建設(shè),讓網(wǎng)站在手機(jī)、平板、PC、微信下都能呈現(xiàn)。建站過程建立專項(xiàng)小組,與您實(shí)時(shí)在線互動(dòng),隨時(shí)提供解決方案,暢聊想法和感受。

Reactive的誕生

談起UI總會(huì)講到MVC,它出現(xiàn)的時(shí)間很早,那時(shí)候還沒有普及現(xiàn)代GUI廣泛使用的事件驅(qū)動(dòng)(消息循環(huán))模型,所以很長(zhǎng)的時(shí)間內(nèi),MVC都在進(jìn)化,不斷的被重新定義。到現(xiàn)在MVC已經(jīng)是一個(gè)很寬泛的概念了。使用基礎(chǔ)的MVC作為框架來開發(fā)容易出現(xiàn)模塊職責(zé)邊界模糊,邏輯調(diào)用方向混亂。GUI框架進(jìn)化后,將用戶事件的分發(fā)處理集成到了View模塊中,由此出現(xiàn)了MVP,MVP職責(zé)劃分較清晰,邏輯調(diào)用方向也比較好把握,但是很繁瑣,開發(fā)效率不高。再隨著Web的發(fā)展,標(biāo)記語言被應(yīng)用于界面描述,開始出現(xiàn)邏輯界面分離和無狀態(tài)化界面,MVVM應(yīng)運(yùn)而生。MVVM讓架構(gòu)層面來提供數(shù)據(jù)和View的雙向綁定,減輕了開發(fā)工作,但有時(shí)候也帶來了一定程度的狀態(tài)混亂。函數(shù)式編程在近年被重新提起,并引發(fā)潮流,催生了響應(yīng)式界面開發(fā),響應(yīng)式是對(duì)GUI事件驅(qū)動(dòng)模型的一種返璞歸真。

個(gè)人對(duì)前端架構(gòu)迭代的理解:

Flutter React編程的方法是什么

從迭代歷程上看,Model和View是兩個(gè)相對(duì)固定的角色,它們?nèi)菀桌斫?,也能很好的確定職責(zé)邊界。如何去溝通Model和View是架構(gòu)設(shè)計(jì)的關(guān)鍵,響應(yīng)式的一般做法是讓Model回到最初的事件驅(qū)動(dòng),結(jié)合函數(shù)式的數(shù)據(jù)流來驅(qū)動(dòng)View刷新。這樣有比較清晰的角色劃分和簡(jiǎn)單易于理解的邏輯鏈接,能較好的統(tǒng)一編程模式。

Flutter React編程的方法是什么

Flutter的Reactive特性

通常GUI框架都有一些共同點(diǎn),比如View的樹形層級(jí),消息循環(huán),Vsync信號(hào)刷新等,F(xiàn)lutter也繼承這些經(jīng)典的設(shè)計(jì),但是Flutter并沒有使用標(biāo)記語言來描述界面(例如Web中的HTML,Android中的XML),這其中有Flutter立足于響應(yīng)式的初衷。Reactive是一款將事件數(shù)據(jù)流作為核心的開發(fā)模型,UI框架會(huì)提供相應(yīng)的特性來提供更好的支持。

1.描述界面而不要操作界面

有一種說法認(rèn)為函數(shù)式語言和命令式語言的不同在于命令式語言是給計(jì)算機(jī)下達(dá)指令而函數(shù)式語言是向計(jì)算機(jī)描述邏輯。這種思路在Flutter UI中得到了體現(xiàn)。Flutter不提倡去操作UI,它當(dāng)然也基本不會(huì)提供操作View的API,比如我們常見的類似TextView.setText(),Button.setOnClick()這種是不會(huì)有的。對(duì)界面的描述是可以數(shù)據(jù)化的(類似XML,JSON等),而對(duì)界面的操作是很難數(shù)據(jù)化的,這很重要,響應(yīng)式需要方便可持續(xù)的將數(shù)據(jù)映射成界面。

Flutter React編程的方法是什么

在Flutter中用Widget來描述界面,Widget只是View的“配置信息”,編寫的時(shí)候利用Dart語言一些聲明式特性來得到類似結(jié)構(gòu)化標(biāo)記語言的可讀性。不論Stateless Widget 還是 Stateful Widget都是不可變的(immutable),其中的成員變量也應(yīng)該都是final的,也就是說,Widget是“只讀”的。Widget是數(shù)據(jù)的映射,當(dāng)數(shù)據(jù)改變的時(shí)候,我們需要重新創(chuàng)建Widget去更新界面,這意味著Widget會(huì)創(chuàng)建銷毀的非常頻繁,不過Flutter使用的Dart虛擬機(jī)能高效的處理這種短周期的輕量對(duì)象。

這種設(shè)計(jì)思路對(duì)剛接觸的開發(fā)者可能有些不習(xí)慣,我們可以借助開發(fā)Android中的ListView(iOS中的TableView)來理解:我們通常先準(zhǔn)備好一個(gè)數(shù)據(jù)List,然后實(shí)現(xiàn)一個(gè)Adapter來將List中的items映射成一個(gè)個(gè)itemView,最后將List和Adapter設(shè)置給ListView。這樣當(dāng)我們改變List中的數(shù)據(jù),ListView就會(huì)相應(yīng)的刷新View。Flutter類似,我們準(zhǔn)備好Widgets(只不過Widget的“容器”是Tree而不是List),F(xiàn)lutter會(huì)提供Adapter(RenderObjectToWidgetAdapter)將其映射成渲染用的RenderObject,當(dāng)Widget更新時(shí)就會(huì)刷新界面。

Flutter React編程的方法是什么

另外,Widget也能通過設(shè)置Key來緩存復(fù)用,在類似ListView的場(chǎng)景中,Item Widget的復(fù)用是很有收益的。

2.基于共同祖先通信

在我們國(guó)家,如果你想和別人溝通上拉近距離,有時(shí)候會(huì)進(jìn)入到類似“我們500年前是一家”的這種語境中。在Flutter中,如果兩個(gè)組件要通信,也是去找祖先(當(dāng)然,也有可能兩個(gè)組件本身就有遺傳關(guān)系),F(xiàn)lutter把它描述成“數(shù)據(jù)上行,通知下行”。

Flutter React編程的方法是什么

但是,在一個(gè)非常復(fù)雜的樹形層級(jí)中,要找到某位“祖先”并不是很容易的事情,而且性能也不好。Flutter為此做了優(yōu)化,提供了InheritedWidget,“祖先”Widget繼承該類型后,child可以通過BuildContext中提供的inheritFromWidgetOfExactType方法方便的找到在層級(jí)中離的最近的那位“祖先”。該方法做了優(yōu)化,效率很高,并且可以讓child和“祖先”建立依賴關(guān)系,方便做刷新。

Flutter中并沒有提倡類似controller的概念(像Android中的Activity,iOS中的ViewController),本身View是不可操作的,controller也就失去了意義。那么,組件之間的通信就必須在View層“自力更生”了。

3.函數(shù)式數(shù)據(jù)流

這肯定不是Flutter才有的,要想把響應(yīng)式實(shí)現(xiàn)的簡(jiǎn)潔優(yōu)雅,就要利用好語言的函數(shù)式特性。Flutter的亮點(diǎn)是它使用的Dart語言能把這件事情變的很輕量,你基本不需要引入什么第三方庫(kù)就能做到(不過確實(shí)有RxDart庫(kù),但感覺只是做了額外的增強(qiáng)),而且明顯語言Api的設(shè)計(jì)也往這個(gè)方向上做了優(yōu)化,非常方便。具體可以看看Stream和RxDart。

基于React的框架實(shí)踐

統(tǒng)一狀態(tài)管理和單向數(shù)據(jù)流

通過React的實(shí)踐,響應(yīng)式可以很好的解決數(shù)據(jù)到界面的更新,而且效率也不錯(cuò)。但是自身對(duì)數(shù)據(jù)狀態(tài)的管理不足,React官方提出了Flux,而在面對(duì)復(fù)雜業(yè)務(wù)場(chǎng)景時(shí),F(xiàn)lutter官方也是推薦Redux架構(gòu),我們也是根據(jù)這一思路搭建的框架。

Flutter React編程的方法是什么

首先是業(yè)務(wù)邏輯和界面分離,界面是無狀態(tài)(Stateless)的,我們也正在嘗試自動(dòng)化的方法直接生成界面代碼,所以Widget中是不會(huì)有業(yè)務(wù)邏輯代碼的。當(dāng)我們把一個(gè)能描述當(dāng)前界面的數(shù)據(jù)(State)交給View層時(shí),界面就應(yīng)該能正常展示。用戶和界面交互會(huì)產(chǎn)生Action,Action代表了用戶交互的意圖,Action可以攜帶信息(比如用戶使用輸入留言,Action中就應(yīng)該攜帶用戶留言的內(nèi)容信息)。Action會(huì)輸入給Store,Store會(huì)通過注冊(cè)的Interrupters對(duì)Action做前期攔截處理,可以通過Interrupter截?cái)rAction,也可以把一個(gè)Action重新改寫成另外的Action。Store然后收集相應(yīng)綁定的Reducers對(duì)Action做一次reduce操作,產(chǎn)生新的State,并通知界面刷新。

通常我們?cè)趧?chuàng)建Store的時(shí)候就組冊(cè)好Reducer和Interrupter:

  Store buildPublishStore(String itemId) {//設(shè)置狀態(tài)初始值

  PublishState initState = new PublishState();

  initState.itemId = itemId;

  initState.isLoading = true;//創(chuàng)建Reducer和對(duì)應(yīng)Action的綁定

  var reducerBinder = ActionBinder.reducerBinder()

  ..bind(PublishAction.DETAIL_LOAD_COMPLETED, _loadCompletedReducer)

  ..bind(PublishAction.DELETE_IMAGE, _delImageReducer)

  ..bind(PublishAction.ADD_IMAGE, _addImageReducer);//創(chuàng)建Interrupter和對(duì)應(yīng)Action的綁定

  var interrupterBinder = ActionBinder.interrupterBinder()

  ..bind(PublishAction.LOAD_DETAIL, _loadDataInterrupter)

  ..bind(PublishAction.ADD_IMAGE, UploadInterruper.imageUploadInterrupter); //創(chuàng)建Store

  return new CommonStore(

  name: 'Publish',

  initValue: initState,

  reducer: reducerBinder,

  interrupter: interrupterBinder);

  }

Reducer中就是處理用戶交互時(shí)產(chǎn)生的Action的邏輯代碼,接收3個(gè)參數(shù),一個(gè)是執(zhí)行上下文,一個(gè)要處理的Action,一個(gè)是當(dāng)前的State,處理結(jié)束后必須返回新的State。函數(shù)式理想的Reducer應(yīng)該是一個(gè)無副作用的純函數(shù),顯然我們不應(yīng)該在Reducer中去訪問或者改變?nèi)钟虻淖兞浚袝r(shí)候我們會(huì)對(duì)前面的計(jì)算結(jié)果有依賴,這時(shí)可以將一些運(yùn)行時(shí)數(shù)據(jù)寄存在ReduceContext中。Reducer中不應(yīng)該有異步邏輯,因?yàn)镾tore做Reduce操作是同步的,產(chǎn)生新State后會(huì)立即通知界面刷新,而異步產(chǎn)生對(duì)State的更新并不會(huì)觸發(fā)刷新。

  PublishState _delImageReducer(ReduceContext ctx, Action action, PublishState state) {int index = action.args.deleteId;

  state.imageUplads.removeAt(index);return state;

  }

  Interrupter形式上和Reducer類似,不同的是里面可以做異步的邏輯處理,比如網(wǎng)絡(luò)請(qǐng)求就應(yīng)該放在Interrupter中實(shí)現(xiàn)。

*為什么會(huì)有Interrupter呢?換一個(gè)角度,我們可以把整個(gè)Store看成一個(gè)函數(shù),輸入是Action,輸出的是State。函數(shù)會(huì)有副作用,有時(shí)我們輸入?yún)?shù)并不一定得會(huì)相應(yīng)有輸出,比如日志函數(shù)( void log(String) ),我們輸入String只會(huì)在標(biāo)準(zhǔn)輸出上打印一個(gè)字符串,log函數(shù)不會(huì)有返回值。同樣,對(duì)Store來說,也不是所有的Action都要去改變State,用戶有時(shí)候觸發(fā)Action只要想讓手機(jī)震動(dòng)下而已,并不會(huì)觸發(fā)界面更新。所以,Interrupter就是Store用來處理副作用的。

  ///截?cái)r一個(gè)網(wǎng)絡(luò)請(qǐng)求的Action,并在執(zhí)行請(qǐng)求網(wǎng)絡(luò)后發(fā)出新Action

  bool _onMtopReq(InterrupterContext ctx, Action action) {

  NetService.requestLight(

  api: action.args.api,

  version: action.args.ver,params: action.args.params,

  success: (data) {

  ctx.store.dispatch(Action.obtain(Common.MTOP_RESPONSE)

  ..args.mtopResult = 'success'

  ..args.data = data);

  },

  failed: (code, msg) {

  ctx.store.dispatch(Action.obtain(Common.MTOP_RESPONSE)

  ..args.mtopResult = 'failed'

  ..args.code = code

  ..args.msg = msg);

  });return true;

  }

通常我們會(huì)讓一個(gè)界面根部的InheritedWidget來持有Store,這樣界面上的任何Widget都能方便的訪問到Store,并和Store建立聯(lián)系。這種做法可以參考redux_demo,再此不詳細(xì)展開。

最后簡(jiǎn)單的說說Store的實(shí)現(xiàn),Store能夠接收Action,然后執(zhí)行reduce,最后向widget提供數(shù)據(jù)源。Widget可以基于提供的數(shù)據(jù)源建立數(shù)據(jù)流,響應(yīng)數(shù)據(jù)變更來刷新界面。這其中最核心的就是Dart的Stream。

  ......

  //創(chuàng)建分發(fā)數(shù)據(jù)的Stream

  _changeController = new StreamController.broadcast(sync: false);//創(chuàng)建接收Action的Stream

  _dispatchController = new StreamController.broadcast(sync: false);//設(shè)置響應(yīng)Action的函數(shù)

  _dispatchController.stream.listen((action) {

  _handleAction(action);

  });

  ......

  //向Store中分發(fā)Action

  void dispatch(Action action) {

  _dispatchController.add(action);

  }

  //Store向外提供的數(shù)據(jù)源

  Stream get onChange => _changeController.stream;

  Store中最核心的對(duì)Action進(jìn)行reduce操作:

  //收集該Action綁定的Reducer

  final List> reducers = _reducers.values

  .where((ctx) => ctx._handleWhats.any((what) => what == action.what))

  .toList();

  //執(zhí)行reduce

  Box box = new Box(action, _state);

  box = reducers.fold(box, (box, reducer) {

  box.state = reducer._onReduce(box.action, box.state);return box;

  });

  //觸發(fā)更新

  _state = box.state;

  _changeController.add(_state);

  Widget基于Store暴露的數(shù)據(jù)源建立數(shù)據(jù)流:

  store.onChange//將Store中的數(shù)據(jù)轉(zhuǎn)換成Widget需要的數(shù)據(jù)

  .map((state) => widget.converter(state))

  //比較前一次數(shù)據(jù),如果想等則不用更新界面

  .where((value) => (value != latestValue))

  //更新界面

  .listen((value){

  ...

  setState()

  ...

  })

組件化的擴(kuò)展

我們?cè)跇I(yè)務(wù)開發(fā)中發(fā)現(xiàn),有時(shí)候一個(gè)頁(yè)面一個(gè)Store會(huì)帶來組件復(fù)用上的不方便,比如視頻播放組件是一個(gè)邏輯比較內(nèi)聚的組件,如果把它的reducer都集中放在頁(yè)面的Store中那么別的頁(yè)面想要復(fù)用這個(gè)開發(fā)好的視頻組件就不方便了,這時(shí)候視頻組件可能需要一個(gè)獨(dú)立的Store來存放視頻播放相關(guān)的邏輯。我們遵循Flutter組件通信方法,將框架擴(kuò)展為允許存在多個(gè)Store,并且做到對(duì)Widget開發(fā)無感知。

Flutter React編程的方法是什么

Widget只能感知離它最近的Store持有者,該Store會(huì)向更高層級(jí)Store轉(zhuǎn)發(fā)Action,同時(shí)接收來自更高層級(jí)Store的數(shù)據(jù)變更并通知Widget。

到此,關(guān)于“Flutter React編程的方法是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!


網(wǎng)站標(biāo)題:FlutterReact編程的方法是什么-創(chuàng)新互聯(lián)
文章起源:http://weahome.cn/article/ijgih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部