React 组件开发入门

前言

熟悉 React 的思想后,咱们先来尝试开发一个单纯的小组件,能够对比一下是否是比之前的开发模式更加温馨了,这里我主要以一个 Loadding 组件来举栗子,实现了几个基本的功能:react

  • 一种类型的 loadding(菊花转)
  • 可以设置 loadding 的三个属性:width height color
  • 可以控制 loadding 的显示和隐藏

其实对于一个简单需求来讲,这三个属性已经很实用了。可是去网上看一些外国大神写的组件,有一些不明白的地方,因此本身就慢慢搞,do it!web

设计

我想这样用 loadding 组件:动画

使用代码

因此我定义这个组件的基本结构以下:this

var Loadding = React.createClass({
	// 控制组件属性的类型
	propTypes: {},
	// 控制组件属性的默认值
	getDefaultProps: function () {},
	// 组装基本的内联样式
	getComponentStyle: function () {},
	// 渲染基本的组件,拆分 render 方法的粒度
	renderBaseComp: function () {},
	// 最终的渲染方法
	render: function () {}
});

这个组件中,我使用的 内联样式 来控制组件的内部基本样式的稳定。其实有时候咱们会以为内联样式很差,可是我我的以为每一种设置 CSS 形式的方法,用在合适的场景中就是正确的。spa

每部分的具体实现以下,代码中有一些讲解(这里我不会介绍具体 loadding 效果是怎么出来的,看代码应该就会明白,主要介绍一个 react 制做简单组件的思路和写法)对于扩展性来讲,.net

你还能够加入 className 和 type 这些修饰性的属性,可是我更倾向于迭代式的组件开发,小组件就要具备良好的封闭性,使用接口简单,大组件才考虑更好的鲁棒性和可扩展性,这样开发一个组件的性价比才高。须要注意对 getDefaultProps 的理解,只有当使用接口的人代码中根本没有写那个属性的时候,才会使用定义的默认值。设计

实现

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(不考虑不支持的状况,不支持都不用开发,直接用图,性价比更高)code

[@include](https://my.oschina.net/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](https://my.oschina.net/extend) .top;
		}
		[@for](https://my.oschina.net/362326) $i from 1 through 4 {
			&:nth-child(#{$i}) {
				transform:rotate(45deg * ($i - 1));
				.top {
					[@include](https://my.oschina.net/include) animation(load, 0.8s, linear, 0s, infinite);
				}
				.bottom {
					[@include](https://my.oschina.net/include) animation(load, 0.8s, linear, 0.4s + $i/10, infinite);
				}
			}
		}
	}
}

里面用到的一个 animation 混淆方法:orm

@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;
}
相关文章
相关标签/搜索