React 組件開發入門
前言
熟悉 React 的思想后,我們先來嘗試開發一個單純的小組件,可以對比一下是不是比以前的開發模式更加舒適了,這里我主要以一個 Loadding 組件來舉栗子,實現了幾個基本的功能:
- 一種類型的 loadding(菊花轉)
- 能夠設置 loadding 的三個屬性:width height color
- 能夠控制 loadding 的顯示和隱藏 </ul>
其實對于一個簡單需求來說,這三個屬性已經很實用了。但是去網上看一些外國大神寫的組件,有一些不明白的地方,所以自己就慢慢搞,do it!
設計
我想這樣用 loadding 組件:
所以我定義這個組件的基本結構如下:
var Loadding = React.createClass({
// 控制組件屬性的類型
propTypes: {},
// 控制組件屬性的默認值
getDefaultProps: function () {},
// 組裝基本的內聯樣式
getComponentStyle: function () {},
// 渲染基本的組件,拆分 render 方法的粒度
renderBaseComp: function () {},
// 最終的渲染方法
render: function () {}
});這個組件中,我使用的 內聯樣式 來控制組件的內部基本樣式的穩定。其實有時候我們會覺得內聯樣式不好,但是我個人覺得每一種設置 CSS 形式的方法,用在合適的場景中就是正確的。
每部分的具體實現如下,代碼中有一些講解(這里我不會介紹具體 loadding 效果是怎么出來的,看代碼應該就會明白,主要介紹一個 react 制作簡單組件的思路和寫法)對于擴展性來說,
你還可以加入 className 和 type 這些修飾性的屬性,但是我更傾向于迭代式的組件開發,小組件就要具有良好的封閉性,使用接口簡單,大組件才考慮更好的魯棒性和可擴展性,這樣開發一個組件 的性價比才高。需要注意對 getDefaultProps 的理解,只有當使用接口的人代碼中根本沒有寫那個屬性的時候,才會使用定義的默認值。
</div>實現
var Loadding = React.createClass({
propTypes: {
width: React.PropTypes.oneOfType([
React.PropTypes.number,
React.PropTypes.string
]),
height: React.PropTypes.oneOfType([
React.PropTypes.number,
React.PropTypes.string
]),
color: React.PropTypes.string,
active: React.PropTypes.bool
},
getDefaultProps: function() {
return {
color: '#00be9c',
height: 30,
width: 30,
active: false
};
},
getComponentStyle: function() {
var width = this.props.width,
height = this.props.height,
color = this.props.color;
/* 中間圓心 */
var cWidth = 0.4 * width,
cHeight = 0.4 * height,
cMarginLeft = -0.5 * cWidth,
cMarginTop = -0.5 * cHeight;
/* 基本樣式 */
return {
loaddingStyle: { // loadding 容器
width: width,
height: height
},
lineStyle: { // loadding 元件樣式
background: color
},
centerStyle: { // loadding 圓心樣式
width: cWidth,
height: cHeight,
marginLeft: cMarginLeft,
marginTop: cMarginTop
}
};
},
renderBaseComp: function(compStyle) {
/* 生成動畫元件 */
var n = 4; // 元件個數,todo: 定制個數
var lines = []; // 元件元素集合
for (var i = 0; i < n; i++) {
lines.push(
<div className="line">
<span className="top" style={ compStyle.lineStyle }></span>
<span className="bottom" style={ compStyle.lineStyle }></span>
</div>
);
}
return lines;
},
render: function() {
/* 生成組件自己的樣式 */
var compStyle = this.getComponentStyle();
/* 模擬渲染基本動畫元件 */
var lines = this.renderBaseComp(compStyle);
// loadding 的class,控制交互
var loaddingClasses = cx({
loadding: true,
active: this.props.active
});
return (
<div className={ loaddingClasses } style={ compStyle.loaddingStyle }>
{lines}
<div className="loadding-center" style={ compStyle.centerStyle }></div>
</div>
);
}
});最后,下面是基本的 SASS(不考慮不支持的情況,不支持都不用開發,直接用圖,性價比更高)
@include keyframes(load) {
0% {
opacity: 0;
}
25% {
opacity: .25;
}
50% {
opacity: .5;
}
75% {
opacity: .75;
}
100% {
opacity: 1;
}
}
.loadding {
display: none;
position: absolute;
&.active {
display: block;
}
.loadding-center {
position: absolute;
left: 0;
top: 50%;
background: #fff;
border-radius: 50%;
}
.line {
position: absolute;
top: 0;
left: 0;
height: 100%;
.top {
content: '';
display: block;
width: 1px;
font-size: 0;
height: 50%;
}
.bottom {
@extend .top;
}
@for $i from 1 through 4 {
&:nth-child(#{$i}) {
transform:rotate(45deg * ($i - 1));
.top {
@include animation(load, 0.8s, linear, 0s, infinite);
}
.bottom {
@include animation(load, 0.8s, linear, 0.4s + $i/10, infinite);
}
}
}
}
}里面用到的一個 animation 混淆方法:
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@-ms-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}
@mixin animation ($name, $duration, $func, $delay, $count, $direction: normal) {
-webkit-animation: $name $duration $func $delay $count $direction;
-moz-animation: $name $duration $func $delay $count $direction;
-o-animation: $name $duration $func $delay $count $direction;
animation: $name $duration $func $delay $count $direction;
} 本文由用戶 er74 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!