標籤:
React是現在主流的高效的前端架構,其官方文檔 http://reactjs.cn/react/docs/getting-started.html 在介紹組件間通訊時只給出了父子組件間通訊的方法,而沒有給出獨立組件間通訊的解決方案。這裡我介紹一種不錯的實現方式——signals.
第一步,我們要建立兩個簡單的react組件——一個進度條和一個輸入框。 組件——進度條:
var ProcessBar=React.createClass({ getInitialState:function(){ return { initValue:0, //初始值 endValue:0, //終值 totalValue:100 , //總值 }; }, render:function(){ var barStyle={ width:this.getPer(), }; return( <div className="progress"> <div className="progress-bar" style={barStyle}>{this.getPer()}</div> </div> ); } });
這個進度條的實現依賴於Bootstrp的進度條組件樣式及特效,可以移步:http://v3.bootcss.com/components/#progress 查看。
組件——input框:
var Input=React.createClass({ getEndValue:function(){ var curValue=this.refs.endValue.value; if(curValue <= 0) curValue=0; if(curValue >=100) curValue=100; }, render:function(){ return ( <div> <input type="text" ref="endValue" placeholder="請輸入值" onChange={this.getEndValue}/> </div> ); } });
兩個獨立的簡單的組件已經完成了,下面就來看看如何使它們可以緊密聯絡,當input框中的值變化時,進度條可以即時變化。
在此,你可以借鑒另一篇部落格瞭解解決獨立組件間通訊的幾種策略——http://www.tuicool.com/articles/AzQzEbq。
這裡,我主要介紹signals解決的方案。我們簡單看下signals的github上的介紹:http://millermedeiros.github.io/js-signals/,看它給出的應用基本執行個體:
//custom object that dispatch a `started` signalvar myObject = { started : new signals.Signal()};function onStarted(param1, param2){ alert(param1 + param2);}myObject.started.dispatch(‘foo‘, ‘bar‘); //dispatch signal passing custom parameters
myObject.started.add(onStarted); //add listener
myObject.started.remove(onStarted); //remove a single listener
我們會發現,signals應用很簡單,步驟為:
1:先建立一個signals.Signal的執行個體對象。
2:該對象通過dispatch()方法發布資料。
3:該執行個體對象提供add(function(data){})方法監聽到資料,data預設為發布的資料。
4:如果需要,可以通過remove()關閉串連。
這裡要提一下,就是因為發布和監聽只能建立一個,所以我們的資料可以集中為一個資料對象,這樣就可以大量傳遞資料了。
好,現在我們來應用到我們的組件中看看能不能解決我們的問題。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>processBar</title> <link rel="stylesheet" href="../../public/css/bootstrap-theme.min.css"/> <link rel="stylesheet" href="../../public/css/bootstrap.min.css"/> <script src="../../public/js/react-0.14.0.js"></script> <script src="../../public/js/react-dom-0.14.0.js"></script> <script src="../../public/js/jquery.js"></script> <script src="../../public/js/browser.min.js"></script> <script src="../../public/js/signals.js"></script> <script src="../../public/js/bootstrap.min.js"></script> <style> #exm{margin:20px auto;height:100px;border:1px solid #000;} .progress-bar{width:60%;} </style></head><body> <div id="exm"></div> <div id="exm2"></div> <script type="text/babel"> //設定資料廣播 var broadData=new signals.Signal(); //全域資料廣播對象 var datas={}; //總資料對象 var ProcessBar=React.createClass({ getInitialState:function(){ return { initValue:0, //初始值 endValue:0, //終值 totalValue:100 , //總值 }; }, getPer:function(){ var that=this; broadData.add(function(data){ //收聽到資料 that.setState({ endValue:data.curValue, }); }); var per=(this.state.endValue-this.state.initValue)/this.state.totalValue *100+"%"; return per; }, render:function(){ var barStyle={ width:this.getPer(), }; return( <div className="progress"> <div className="progress-bar" style={barStyle}>{this.getPer()}</div> </div> ); } }); //輸入框 var Input=React.createClass({ getEndValue:function(){ var curValue=this.refs.endValue.value; if(curValue <= 0) curValue=0; if(curValue >=100) curValue=100; datas.curValue=curValue; //將curValue放入總數居對象 broadData.dispatch(datas); //發布資料 }, render:function(){ return ( <div> <input type="text" ref="endValue" placeholder="請輸入值" onChange={this.getEndValue}/> </div> ); } }); ReactDOM.render( //input框要先於進度條渲染 <Input/>, document.getElementById("exm2") ); ReactDOM.render( <ProcessBar/>, document.getElementById("exm") ); </script></body></html>
我們的代碼效果如下:
我們的問題得到瞭解決!
如果以上內容對您有所協助,請幫我點個推薦吧,傳播整理知識,有利你我。
React獨立組件間通訊聯動