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

    ...
}
<think>好的,用户之前遇到了在CentOS7上使用sox处理MP3文件时出现“no handler for file extension 'mp3'”的问题,我给出了解决方案,包括安装EPEL和RPM Fusion仓库,安装必要的库如lame和libmad。现在用户按照步骤执行后,执行sox --help | grep -i mp3仍然没有输出,无法转换MP3。需要进一步分析可能的原因。 首先,用户已经安装了所需的仓库和库,但sox仍然不支持MP3。可能的原因包括: 1. 软件包未正确安装:可能某些依赖包没有安装,或者安装过程中出现错误,导致sox未能正确链接到MP3库。 2. 版本问题:CentOS7的默认仓库中的sox可能较旧,即使安装了依赖项,也可能没有启用MP3支持。 3. 动态库路径问题:系统可能没有正确找到libmad或lame的库文件,导致sox无法加载这些模块。 4. 编译选项问题:通过仓库安装的sox可能在编译时没有包含MP3支持,需要重新编译。 需要进一步验证用户是否正确安装了所有必要的软件包,并检查sox是否真的链接到了这些库。例如,使用ldd命令查看sox的依赖关系,确认是否存在libmad和libmp3lame。如果这些库没有被链接,可能需要手动编译sox并启用相关选项。 另外,用户可能需要确认安装的sox版本是否支持MP3。有些情况下,即使依赖库存在,sox也可能需要特定的编译标志才能启用MP3支持。如果仓库中的sox包没有启用这些标志,用户可能需要从源码编译安装。 还可能存在路径问题,比如库文件安装在非标准目录,导致sox无法找到。这时需要检查LD_LIBRARY_PATH环境变量,或者将库路径添加到配置文件中。 最后,如果所有方法都无效,建议用户使用替代工具如ffmpeg来处理MP3文件,这可能更简单可靠。</think>--- ### **问题分析** 当您已完成所有正确安装步骤,但 `sox --help | grep -i mp3` 仍无输出时,表明 `sox` 仍未正确加载 MP3 支持。可能原因如下: | 原因类型 | 具体表现 | |------------------|------------------------------------------------------------------------| | **依赖未正确链接** | `sox` 编译时未启用 MP3 支持,或动态库路径未正确配置 | | **多版本冲突** | 系统中存在多个 `sox` 版本(如通过 `yum` 和源码安装的版本混合) | | **SELinux 限制** | 安全策略阻止了音频编解码库的加载 | --- ### **分步解决方案** #### **1. 验证依赖完整性** ```bash # 检查关键软件包是否安装(必须全部存在) rpm -qa | grep -E 'sox|lame|libmad' # 预期输出应包含: # sox-14.4.1-xxx.el7.x86_64 # lame-3.100-xxx.el7.x86_64 # libmad-0.15.1b-xxx.el7.x86_64 # 若缺失则重新安装 sudo yum reinstall sox lame libmad ``` #### **2. 检查动态库链接** ```bash # 查看 sox 的 MP3 编解码库是否被正确链接 ldd $(which sox) | grep -E 'mad|lame' # 正常应输出类似: # libmad.so.0 => /usr/lib64/libmad.so.0 (0x00007f...) # libmp3lame.so.0 => /usr/lib64/libmp3lame.so.0 (0x00007f...) # 若无输出,手动添加库路径 echo '/usr/lib64' | sudo tee /etc/ld.so.conf.d/audio.conf sudo ldconfig ``` #### **3. 强制启用 MP3 支持** ```bash # 检查当前支持的格式 sox --help | grep 'AUDIO FILE FORMATS' -A 30 # 若仍无 MP3,手动指定格式转换 sox -t mp3 1740622002792.mp3 -r 8000 -t mp3 1740622002792_new.mp3 ``` #### **4. 处理 SELinux 限制** ```bash # 临时禁用 SELinux(仅用于测试) sudo setenforce 0 # 若此时 MP3 转换成功,需永久配置策略 sudo semanage boolean -m --on allow_execheap sudo restorecon -v /usr/bin/sox ``` #### **5. 源码编译安装(终极方案)** ```bash # 卸载旧版本 sudo yum remove sox # 安装开发工具链 sudo yum install gcc make autoconf automake libtool libmad-devel lame-devel # 从源码编译 wget https://sourceforge.net/projects/sox/files/sox/14.4.2/sox-14.4.2.tar.gz tar xzf sox-*.tar.gz cd sox-14.4.2 # 关键配置参数 ./configure \ --enable-formats=mp3 \ --with-mad \ --with-lame \ --without-oggvorbis make -j$(nproc) sudo make install # 验证新版 which sox # 应输出 /usr/local/bin/sox sox --version ``` --- ### **替代验证方法** 通过 `strace` 追踪库加载过程: ```bash strace -e openat sox input.mp3 output.wav 2>&1 | grep -i 'mp3\|mad\|lame' # 观察是否有类似以下输出: # openat(AT_FDCWD, "/usr/lib64/sox/libmad.so", ...) ``` --- ### **版本兼容性参考表** | 组件 | 要求版本 | 检查命令 | |------------|----------------------|------------------------| | sox | ≥14.4.1 | `sox --version` | | libmad | ≥0.15.1b | `rpm -q libmad` | | lame | ≥3.100 | `lame --version` | --- ### **常见故障模式** 1. **混合安装导致冲突** 若同时存在 `yum` 安装和源码安装的 `sox`,会导致路径混乱: ```bash # 清理所有安装痕迹 sudo yum remove sox sudo rm -f /usr/local/bin/sox # 重新通过 yum 安装 ``` 2. **32/64 位库混合** 在 64 位系统中误装 32 位库: ```bash # 确认架构一致性 file $(which sox) # 应显示 x86-64 file /usr/lib64/libmad.so # 应显示 ELF 64-bit ``` --- ### **最终验证** 若所有步骤均完成但仍无效,建议: ```bash # 使用 FFmpeg 替代(推荐) ffmpeg -i input.mp3 -ar 8000 -ac 1 -ab 32k output.mp3 # 或用 Python 脚本处理 python3 -c "from pydub import AudioSegment; \ AudioSegment.from_mp3('input.mp3').set_frame_rate(8000).export('output.mp3', format='mp3')" ``` --- 通过上述深度排查,99% 的 MP3 支持问题可以得到解决。如果仍遇到问题,请提供以下信息以便进一步分析: ```bash rpm -qa '*sox*' '*lame*' '*mad*' ldd $(which sox) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值