構造複合型組件

上篇文章中,已使用組件技術,實現了一個“五彩冰粉”的網頁控件。 從中可以體會到,組件其實就是把html, javascript, 和css 以有機的方式結合在一起,形成一個高度可重用的獨立單元

本篇文章中,將研究組件的另一特性,就是它的組合性,React組件 技術的一大殺傷力在於,它能讓我們通過把微小簡單的組件結合起來,進而創造出複雜強大的複合組件,

把控件分解成 若干個簡單的控件,然後把這些簡單小控件組合起來,最終形成我 們想要的頁面組件,調色板控件如圖,在
文本框中輸入顏色的數值,點擊 回車,文本框上面的小版塊就會改變成文本框中輸入的數值相一致 的顏色


我們可以把這個控件分成兩部分,一部分是上面用於顯示顏色的 小方塊,我們可以稱之爲顯色板,另一部分就是下邊的文本輸入框 。
於是,要完成這個控件,我們需要完成三個步驟:

1, 創建一個控件,用於實現顯色板 

2, 創建一個控件,用於實現文本輸入框 

3, 將兩個控件有機結合起來

在代碼中創建三個組件,第1個組件用來構建顯色板,我們把它 命名爲square,

 第2個組件對應的是文本輸入框,我們把它命名爲 label, 

第三個組件作用是把前兩個組件整合起來,形成我們最終 想要的控件。代碼如下:

<script type="text/babel">
    var destination =   document.querySelector("#container");
    var Square  =   React.createClass({
         render:function() {
             return (
                 <p>This is a square</p>
                 );
         }
    });
    var Label = React.createClass({
        render:function() {
            return (
                <p>This is a label</p>
                );
        }
    });
    var Card = React.createClass({
         render: function() {
            var cardStyle = {
                 height:200,
                 width:150,
                 padding:0,
                 backgroundColor:"#FFF",
                 WebkitFilter:"drop-shadow(0px 0px 5px #666)",
                 filter: "drop-shadow(0px 0px 5px #666)"
            };
            return (
                 <div style={cardStyle}>
                    <Square/>
                    <Label/>
                 </div>
            )
        }
    })
    ReactDOM.render(
         <div>
            <Card/>
         </div>,
         destination
    );
</script>

上篇文章提到過,React在設計控件樣式時,可以把原來css的 設計屬性轉變爲js的json對象,與控件的業務邏輯放到一起。 這裏我們需要注意一個屬性叫WebkitFilter, 該屬性與我們以前 提到的命名機制不一樣,我們以前說,屬性的命名要採取駱駝格式 ,也就是首單詞小寫,第二個大小,依次類推,但這裏,該屬性 首個單詞就大寫了,這是因爲這個屬性是專門針對webkit內核的 瀏覽器的,所以,當某個屬性是針對某個具體廠商開發的瀏覽器 時,該屬性第1個單詞的首字母要大寫。

接下來,處理控件上面的顯色板部分,同理我們先定義顯色板 的顯示樣式,添加代碼如下:

var Square  =   React.createClass({
     render:function() {
         var squareStyle ={
             height:150,
             backgroundColor:"#FF6663"
         }
         return (
             <div style={squareStyle}>
                <p>This is  a   square</p>
             </div>
             );
        }
});

繼續完善下面的文本框 輸入控件:

var Label   =   React.createClass({
    render:function() {
     var labelStyle  =   {
         fontFamily:"sans-serif",
         fontWeight:"bold",
         padding:13,
         margin:0
     };
     return (
         <p style={labelStyle}>#FF6663</p>
         );
    }
});

完成以上代碼後,整個控件的基本樣式已經成型,接下來我們把 精力集中到控件的業務邏輯上

現在,控件有一個問題,就是上面顯色板顯示的顏色和下面文本框顯示的字符,是在代碼裏寫死的,最後要完成的控件 ,其功能是讓用戶輸入顏色,然後顯色板根據用戶輸入改變它該 顯示的顏色。解決這個問題的辦法,那就是 依賴控件的屬性機制。

當前控件需要動態可變的有兩部分,一部分上顯色板的背景色,該 顏色需要根據用戶的輸入進行相應變動,另一部分是下面文本框的 輸入內容。因此我們需要做的改變是將這兩部分的屬性設置由原來 的寫死轉變爲從外部通過屬性傳遞進來,因此代碼做如下改變:

var Square  =   React.createClass({
    render:function() {
        var squareStyle =   {
            height:150,
            backgroundColor:   this.props.color
        }
        return (
            <div   style={squareStyle}>
                <p>This is  a   square</p>
            </div>
        );
    }
});
var Label   =   React.createClass({
    render:function() {
        var labelStyle = {
            fontFamily:"sans-serif",
            fontWeight: "bold",
            padding:13,
            margin: 0
        };
    return (
        <p style={labelStyle}>{this.props.color}</p>
        );
    }
});

由於這兩個控件間套在父控件Card的內部,因此用戶如果想要把 信息傳遞給它們,那麼信息需要先傳遞給父控件Card,然後通過父控件Card再次傳遞給這兩個子控件,因此代碼修改如下:

var Card = React.createClass({
     render:function() {
         var cardStyle = {
             height: 200,
             width: 150,
             padding: 0,
             backgroundColor: "#FFF",
             WebkitFilter:"drop-shadow(0px   0px 5px #666)",
             filter:    "drop-shadow (0px   0px 5px #666)"
         };
         return (
             <div style={cardStyle}>
                <Square color={this.props.color
                <Label  color={this.props.color
             </div>
             );
        }
    });
    ReactDOM.render(
         <div>
            <Card color="#FF6663"/>
         </div>,
         destination
    );
加載修改的代碼後,我們可以看到顯色板的顏色和下面文本框的文本已經改變了

總結:

 本節,我們我們注重的是組件的組合特性,也就是一個複雜的組件可以通過多個簡單的小組件組合而成。此篇文章先觀察一個最終組件是怎樣的,然後倒推回去,把整個大組件分割成兩個小組件的結合。

把大組件分割成小組件,分別實現每個小組件後,接下來的問題是 如何把零散的小組件組合起來,把小組件作爲大組件的子控件 ,把他們間套在大控件所對應的標籤中。同時需要注意到,內部控件的屬性想要獲得外部輸入進行, 需要先把屬性值提交給父控件,然後再由父控件把獲得的信息轉移 給它內部的子控件,內部子控件是不能直接獲取外部信息的。

當前控件存在一個問題是,下面文本框不能接收收戶輸入, 要解決這個問題,需要研究React控件的事件響應機制,未完待續 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章