React獨立組件間通信聯動


     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` signal
var 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>

  我們的代碼效果如下:

      

     我們的問題得到了解決!

     所有代碼可以在github上下載——https://github.com/Johnharvy/React-components-combo

     如果以上內容對您有所幫助,請幫我點個推薦吧,傳播整理知識,有利你我。

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM