【问题标题】:React: Convert CSSProperties to Styled-ComponentReact:将 CSSProperties 转换为 Styled-Component
【发布时间】:2020-12-25 12:36:58
【问题描述】:

我有一个格式如下的对象:


    let style:React.CSSProperties|object = {
        marginLeft: '0',
        borderRadius: '20px',
        display: 'flex',
        justifyContent: 'center',
    }

我需要将 React CSSProperties 转换为相应的字符串格式,例如:


    let string_styles:string = `{
        margin-left: 0;
        border-radius: 20px;
        display: flex;
        justify-content: center;
    }`

由于我找不到具体的语法来编写 css,例如 :hover::before::before:hover 内联,所以现在将其用作样式组件,同时保留 CSSProperties 对象以供将来导入.

不优雅,我硬编码了转换方法。

    deQuote(dict:object):string{
        return JSON.stringify(dict).replace(/['"]+/g, '');
    }
    // passin: {marginLeft: '0', borderRadius: '20px'} 
    // return: `{marginLeft: 0, borderRadius: 20px}`

    deBraces(str:string):string{
        return str.substring(1, str.length-1);
    }
    // passin: `{marginLeft: 0, borderRadius: 20px}`
    // return: `marginLeft: 0, borderRadius: 20px`

    deComma(str:string):string{
        return str.split(',').join(';');
    }
    // passin: `marginLeft: 0, borderRadius: 20px`
    // return: `marginLeft: 0; borderRadius: 20px`

    deBase(dict:object):string{
        return deComma(deBraces(deQuote(dict)));
    }
    // passin: {marginLeft: '0', borderRadius: '20px'} 
    // return: `marginLeft: 0; borderRadius: 20px`
    

但这里是棘手的部分,转换需要很多努力

    marginLeft -> margin-left

通过自定义函数解决,

    CSSPropertiesToComponent(dict:React.CSSProperties){
        let str = '';
        for(const [key, value] of Object.entries(dict)){
            let clo = '';
            key.split('').forEach(lt=>{
                if(lt.toUpperCase() === lt){
                    clo += '-' + lt.toLowerCase();
                }else{
                    clo += lt;
                }
            });
            str += clo + ':' + value + ';';
        }
        return str;
    }

但是,如果有更好的方法将 React.CSSProperties 转换为 Styled Component 字符串,请告诉我。

【问题讨论】:

标签: css reactjs typescript styled-components


【解决方案1】:

您可以使用 lodash.kebabCase package 来解决该问题。

这是一个例子

import kebabCase from 'lodash.kebabcase';

kebabCase('Foo Bar');
// => 'foo-bar'
 
kebabCase('fooBar');
// => 'foo-bar'
 
kebabCase('__FOO_BAR__');
// => 'foo-bar'

【讨论】:

  • 我有一个类似的方法,我真的很期待一个更简单的解决方案。 deCap(str:string):string{return str.split('').map(lt=>lt.match(/[A-Z]/) && lt ? `-${lt.toLowerCase()}` : lt).join('');}谢谢你的建议。
【解决方案2】:

为什么需要将对象转换为字符串?

您可以通过它映射并使用Object.keysArray.reduce 方法构建您的最终字符串。

const style = {
    marginLeft: '0',
    borderRadius: '20px',
    display: 'flex',
    justifyContent: 'center',
}

const finalResult = Object.keys(style).reduce((accumulator, key) => {
    // transform the key from camelCase to kebab-case
    const cssKey = kebabCase(key)
    // remove ' in value
    const cssValue = style[key].replace("'", "")
    // build the result
    // you can break the line, add indent for it if you need
    return `${accumulator}${cssKey}:${cssValue};`
}, '')

如果您不想使用 kebabCase 库,可以使用简单的正则表达式查找所有大写字母并将其转换为小写字母并在其前加上 -

const regex = new RegExp(/[A-Z]/g)
const kebabCase = (str) => str.replace(regex, v => `-${v.toLowerCase()}`)

【讨论】:

    猜你喜欢
    • 2022-11-29
    • 2020-01-19
    • 2020-11-20
    • 2019-11-13
    • 2020-07-18
    • 2020-09-06
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    相关资源
    最近更新 更多