書接上文,UI 積累之select sectioncss
這裏又來兩個需求了。react
當我點擊選擇了option後,我應該看到的是我選擇的option的內容segmentfault
多例重用,即一樣是個selection,我只是須要改點東西,其餘不變,好比selection裏面的字內容,font-size, font-family, selection的width, height等。。。如何只開發一個組件就知足這個「無理要求」呢?dom
咱們的dom是這樣的:組件化
<Selectsection> <select> <option>Please select one option...</option> <option>...</option> <option>...</option> </select> <span>Please select one option...</span> <div></div> </Selectsection>
具體實現,經過react的state卻是能很簡單實現。ui
給select綁定個onChange事件,觸發onSelect方法,當選擇select的option的時候,把選到的值傳給真正顯示的spanthis
問題來了:1)怎麼拿。 2)怎麼給spa
1)怎麼拿:設計
點擊的時候,經過event.target.value拿到選中的option的值
2)怎麼給:code
在組件渲染的時候,constructor裏的state定義一個值存放選中的值,叫showValue,當選擇時,在onSelect方法裏,拿到event.target.value後,set給這個值,同時dom中的span進行this.state.showValue值綁定。
完整代碼以下:
class Selection extends Component { constructor(props){ super(props) this.state = { showValue: "Please select one option..." } } onSelect(e){ this.setState({showValue: e.target.value}); } render() { return ( <Selectsection> <select onChange={this.onSelect.bind(this)}> <option>Please select one option...</option> <option>...</option> <option>...</option> </select> <span>{this.state.showValue}</span> <div></div> </Selectsection> ); } }
實例圖:
看上面的代碼能夠知道,引入這個selection的方式是這樣的
render( <Selection /> )
可是你這個selection啊,我同一個頁面要引入N個,其中一個高度要是40px,另外一個寬度要長點,500px,還有一個長寬都不用變,你給我變下這個selection的default的字啊,不叫Please select one option..., 叫什麼Please kindly select one option...,還有一個,你給我保持原樣不變哈,謝謝了。
WTF, 怎麼作呢?
需求啊,莫得辦法
爲了開發方便,我本身設計,要是能組件化,幾個屬性在引入的時候能夠選擇性定義就行了,好比:
render( <div> <Selection /> <Selection width="500px" /> <Selection height="40px" /> <Selection wordings="Please kindly select one option..."/ /> </div> )
能這麼實現就完美了。
怎麼作呢,這就要引入一個包,叫prop-types了,定義屬於這個組件的變量,而後將其運用到組件的每一個dom的css上。
接下來以上述爲例子。
定義屬於這個組件的類型:
Selection.propTypes = { height: PropTypes.oneOfType([ PropTypes.number, PropTypes.string, ]), width: PropTypes.oneOfType([ PropTypes.number, PropTypes.string, ]), words: PropTypes.string } Selection.defaultProps = { height: '30px', width: '300px', words: 'Please select one option...' }
而後就是經過react的this.props引入啦
index.js
class App extends Component { render() { return ( <div> <Selection /> <Selection height="40px" /> <Selection width="500px" /> <Selection words="Please kindly select one option..." /> </div> ); } }
Selection.js
class Selection extends Component { constructor(props){ super(props) this.state = { showValue: this.props.words } } onSelect(e){ this.setState({showValue: e.target.value}); console.log(e.target.value) } render() { const { width, height } = this.props const style = { width: width, height: height } const suitableHeight = (parseInt(height.substring(0, height.length-2)) - 30) / 2 + 6; const spanStyle = { width: width, height: height, paddingTop:suitableHeight } const arrowStyle = { top:suitableHeight } return ( <Selectsection style={style}> <select onChange={this.onSelect.bind(this)} value={this.state.showValue} style={style}> <option>{this.props.words}</option> <option>...</option> <option>...</option> </select> <span style={spanStyle}>{this.state.showValue}</span> <div style={arrowStyle}></div> </Selectsection> ); } } Selection.propTypes = { height: PropTypes.oneOfType([ PropTypes.number, PropTypes.string, ]), width: PropTypes.oneOfType([ PropTypes.number, PropTypes.string, ]), words: PropTypes.string } Selection.defaultProps = { height: '30px', width: '300px', words: 'Please select one option...' }
效果圖:
hm。。。應該差很少了,這裏代碼裏就忽略了
自定義屬性時候純數字和字符串的判斷
當height是比30小的時候的判斷處理
有興趣本身加
ok,完美收工