上篇文章中,已使用組件技術,實現了一個“五彩冰粉”的網頁控件。 從中可以體會到,組件其實就是把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控件的事件響應機制,未完待續