将依照fusion官网,https://fusion.design/component/basic/input
自己实现:https://github.com/nianxiongdi/fusion-next-extract-component
分析input组件,如下:
分析源码:
Base.jsx //封装一下方法和属性
Input.jsx //渲染input
Group.jsx //对input进一步的封装
看官网的api,一步一步的实现所有的方法和属性
Input组件:
value属性
- 当前值 String/Number
// <Input size="large" placeholder="Large" aria-label="Large" value="this is input" />
constructor(props) {
super(props);
let value;
// 判断用户是否传值,若是传,则进行保存到state中
if('value' in props) {
value = props.value;
}else {
value = props.defaultProps;
}
this.state = {
value: typeof value === 'undefined' ? '' : value
// value: !!value ? '' : value 个人认为这样写更好
}
}
size 尺寸
- 可选值: ‘small’(小) |‘medium’(中) | ‘large’(大) Enum(类型) ‘medium’(默认值)
const cls = classNames(this.getClass(), {
[`${prefix}${size}`]: true,
});
defaultValue 初始化
constructor(props) {
super(props);
let value;
// 当用户传value时,为当前值,
if('value' in props) {
value = props.value;
}else { // 若无传value,则选择是defaultValue值
value = props.defaultValue;
}
this.state = {
value: typeof value === 'undefined' ? '' : value
}
}
onChange 发生改变的时候触发的回调
签名 Function(value: String, e: Event) => void
参数:
value: {String} 数据
_e_: {Event} DOM事件对象
- 这里是个回调思想请参考
Base.jsx
getProps() {
const props = {
value: this.state.value,
onChange: this.onChange.bind(this) // 绑定this
}
return props;
}
input.jsx
const inputEl = (
<input
value={value} //这里实现 显示value
{...props}
/>
);
// 用户使用
function handleChange(v, e) {
console.log(v)
}
<Input size="medium" placeholder="Large"
aria-label="Large"
defaultValue="init value"
onChange={handleChange}
/>
onKeyDown 键盘按下的时候触发的回调
- Function(e: Event, opts: Object) => void
Input.js 代码
/**
* 获取字符串的长度, 也可以自定义
**/
getValueLength(value) {
const nv = `${value}`;
//这里判断是否是用户 自定义的方法获取长度,若没有定义 返回的是undefined
let strLen = this.props.getValueLength(nv);
// 若用户没有自定义 则获取的是字符串长度 思想666
if (typeof strLen !== 'number') {
strLen = nv.length;
}
return strLen;
}
Base.js 代码
/**
* 当用户按下之后的操作
**/
onKeyDown(e) {
const value = e.target.value;
const { maxLength } = this.props;
const len = maxLength > 0 && value ? this.getValueLength(value) : 0; // 获取当前的最大长度
const opts = { };
// 去除空格 this.props.trim用户传的 默认为false
if (this.props.trim && e.keyCode === 32) {
opts.beTrimed = true;
}
// has defined maxLength and has over max length and has not input backspace and delete
// 当超出了也为true
if (maxLength > 0 && (len > maxLength + 1 ||
((len === maxLength || len === maxLength + 1) && e.keyCode !== 8 && e.keyCode !== 46)
)) {
opts.overMaxLength = true;
}
this.props.onKeyDown(e, opts)
}
disabled 按钮是否处于禁用状态
在base.jsx:
// 设置 样式
getClass() {
const { disabled, state, prefix } = this.props;
return classNames({
[`${prefix}input`]: true,
[`${prefix}disabled`]: !!disabled,
[`${prefix}error`]: state === 'error',
[`${prefix}focus`]: this.state.focus,
});
}
// 传递给子类
getProps() {
// 这个调用 this.props
const { disabled } = this.props;
}
在input.jsx中:
const cls = classNames(this.getClass(), {
[`${prefix}${size}`]: true,
});
//调用Base组件的 getProps方法
const props = this.getProps();
//渲染
const inputEl = (
<input
value={value} //这里实现 显示value
onKeyDown={this.handleKeyDown}
{...props}
/>
);
maxLength 输入的最大长度
-
maxlength也是原声的input属性
-
这里input原生的有
<input type="text" maxLength="5" name="usrname">
maxLength属性,因此操作如下:
//在Base.jsx中操作:
getProps() {
// 这个调用 this.props
const {
。。。
maxLength
} = this.props;
}
//传递给input.jsx即可
hasLimitHint 是否展现最大长度样式
在base.jsx中:
//渲染最大的长度
renderLength() {
const { maxLength, prefix, hasLimitHint } = this.props;
const len = maxLength > 0 && this.state.value ? this.getValueLength(this.state.value) : 0;
const classesLenWrap = classNames({
[`${prefix}input-len`]: true, //长度的样式
[`${prefix}error`]: len > maxLength // 当超出时,变红
});
const content = `${len}/${maxLength}`;
return maxLength && hasLimitHint ? <span className={classesLenWrap}>{content}</span> : null;
}
在input.jsx中:
//进渲染的函数
renderControl() {
const { prefix } = this.props;
const lenWrap = this.renderLength();
return <span className={`${prefix}input-control`}>
{lenWrap}
</span> ;
}
...
const inputWrap = (<span >
...
{this.renderControl()}
</span>);
cutString 当设置了maxLength时,是否截断超出字符串
在Base.jsx中设置
getProps(){
...
// 这个调用 this.props
const {
...
maxLength,
cutString, // 当设置了maxLength时,是否截断超出字符串
} = this.props;
const props = {
...
maxLength: cutString ? maxLength : undefined, // 进行修改
}
...
}