Css in Js 一次实践

栏目: CSS · 发布时间: 6年前

内容简介:最近需要做一个表格组件,组件需求:最终采用grid实现需求。实现的时候遇到一个问题,如果css和js分开写,css只能是定值,没有灵活性。所以考虑采用在github上找了一下关于这方面的组件,发现styled components 非常不错,简单易上手,

最近需要做一个表格组件,组件需求:

  1. 指定行、列
  2. 可以跨行、跨列
  3. 行和行之间有分割线

最终采用grid实现需求。实现的时候遇到一个问题,如果css和js分开写,css只能是定值,没有灵活性。所以考虑采用 css in js 的形式。关于 css in js 相关的概念介绍可以参考阮一峰老师的文章:css in js 介绍。

在github上找了一下关于这方面的组件,发现styled components 非常不错,简单易上手,

npm下载:`npm i styled-components -S`
复制代码

注意: React < 16 需要下载3.x.x版本的

根据文档先写一个简单的demo。

Css in Js 一次实践

可以看到,它的实现方式并不是传统的以对象的形式写样式,而是将需要添加样式的元素加到styled对象上,然后跟一个(``)反引号标签,在里面以正常的css格式写样式。然后返回一个组件,把组件替换原来的div即可。

实现效果:

Css in Js 一次实践

html代码:

Css in Js 一次实践

css代码:

Css in Js 一次实践

刚才我们添加样式的元素是html元素,那么给组件添加样式可以么?实践一下:

const H1 = ({ className }) => <h3 className={className}>我是App</h3>;
const HH = styled.H1`
  font-size: 30px;
  color: red;
`;
复制代码

运行,报错:

Css in Js 一次实践

咋回事?原来styled不支持以 . 符号的形式为组件添加样式,需要以参数形式传递,修改上面代码

const HH = styled(H1)`
  font-size: 30px;
  color: red;
`;
复制代码

H1 组件以参数形式传递给styled,就可以了。

Css in Js 一次实践

想给元素添加伪元素样式,子元素样式可以么?没问题, styled components 支持样式嵌套,按照类似Less或Scss的书写方式就可以了。

const Container = styled.div`
  width: 300px;
  max-width: 500px;
  min-width: 200px;
  transition: all 1s ease-in-out;
  background-color: rgba(240, 240, 240, 0.9);
  ::after {
    content: 'after';
    display: table;
    color: blue;
  }
  span {
    color: green;
  }
`;
复制代码

以上我们写的组件都是在Class外面,那我们要根据props设定样式怎么办? styled components 同样支持在Class内生成组件,并接受props传递过来的值, 这个props并不是我们的Class接收的props ,它是添加样式的元素上的Props,意思就是

class Demo {
    
    render(){
        return <Styled name="guoshi"></Styled>
    }
}

Demo.defaultProps = {
    age: 18
}

const Styled = styled.p`
    color: ${props=>{console.log(props)}} // {name: "guoshi",theme:{...}}
`

复制代码

如果想使用Class的props怎么办?看代码:

generateStyle = () => {
        const {row, col, justify, data, prefixCls, showborder = true, rowgap = 0, colgap = 0} = this.props;
        const child = [];
        data.map((item,index)=> (item.colSpan || item.rowSpan) ? child.push({index:index+1,colSpan:item.colSpan, rowSpan:item.rowSpan}):null);
        const bordernone = [];
        for(let i = 0; i < row; i++) {
            bordernone.push(1 + i*col);
        }
        const UlContainer = styled.ul.attrs({className: prefixCls})`
                display: grid;
                grid-template-columns: ${()=> {
                    let arr = [];
                    arr.length = col;
                    return arr.fill('1fr').join(' ');
                }};
                grid-template-rows:  ${()=> {
                    let arr = [];
                    arr.length = row;
                    return arr.fill('1fr').join(' ');
                }};
                grid-gap: ${rowgap} ${colgap} ;
                justify-items: ${()=> justify || "center"};

                ::before {
                    display: none;
                }
                
                li {
                    width: 100% !important;
                }

                ${
                     child.map(({index, colSpan, rowSpan}) =>`
                        li:nth-child(${index}) {
                            grid-column-start: ${index%col === 0 ? index : index%col};
                            grid-column-end: ${colSpan ? (colSpan+(index%col === 0 ? index : index%col)) : ((index%col === 0 ? index : index%col)+1)}
                            grid-row-start: ${Math.ceil(index/col)};
                            grid-row-end: ${rowSpan  ? rowSpan+Math.ceil(index/col) : Math.ceil(index/col)+1};
                            align-items: start;
                        }
                     `).join(' ')
                 }
                
                li + li {
                    border-left: 1px dashed rgba(0,0,0,0.3);
                }

                ${
                    bordernone.map(bordernoneindex=>`
                        li:nth-child(${bordernoneindex}) {
                            border-left: none;
                        }
                    `).join(' ')
                }
                
            `;
        
            return UlContainer;
    }
复制代码

提前把最后代码放出来了, styled.ul.attrs({}) 就是为元素添加额外的属性,比如className、placeholder等,从代码中可以看到,无论是Class的props还是元素自身传进来的props,styled都可以接收,你可以自定义任何你想实现的规则,更方便我们配置的灵活性。

其实到这里,使用上没有任何问题了,关于keyframes等规则官网上都有demo,也非常容易实现。想尝试的小伙伴现在就可以码一遍。不过本章遗留了很多问题:

  1. styled.div & styled(div) 有什么区别
  2. 模版字符串中的样式是怎么解析的?为什么可以嵌套?
  3. 为什么会返回一个组件?

下一章,我会根据 styled componnets 源码解答上述问题。

最后,祝生活愉快。


以上所述就是小编给大家介绍的《Css in Js 一次实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript语言精髓与编程实践

JavaScript语言精髓与编程实践

周爱民 / 电子工业出版社 / 2012-3 / 79.00元

《JavaScript语言精髓与编程实践(第2版)》详细讲述JavaScript作为一种混合式语言的各方面特性,包括过程式、面向对象、函数式和动态语言特性等,在动态函数式语言特性方面有着尤为细致的讲述。《JavaScript语言精髓与编程实践(第2版)》的主要努力之一,就是分解出这些语言原子,并重现将它们混合在一起的过程与方法。通过从复杂性到单一语言特性的还原过程,读者可了解到语言的本质,以及“层......一起来看看 《JavaScript语言精髓与编程实践》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具