Fusion之Input组件源码分析

本文详细解析了Fusion设计系统中的Input组件,从Base.jsx、Input.jsx和Group.jsx等核心文件入手,深入探讨了组件的构造方法、属性设置、事件处理及状态管理等关键环节,特别关注value、size、onChange、onKeyDown等重要特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将依照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, // 进行修改
    }

    ...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值