虽互不曾谋面,但希望能和你成为笔尖下的朋友
以读书,技术,生活为主,偶尔撒点鸡汤
不作,不敷衍,意在真诚吐露,用心分享
点击左上方,可关注本刊
撰文 | 川川
VX-ID:suibichuanji
点击文末左下方阅读原文,可看更多内容
前言
React是一个构建用户界面的js库,从UI=render()这个等式中就很好的映射了这一点,UI的显示取决于等式右边的render函数的返回值.
而编写React应用,就是在编写React组件,组件中最重要的数据就是props和state,有了数据,怎么让其以什么样的显示,那就是CSS做的事情了
在React中,一切皆可以是Js,也就是说在js里面可以写css,这相比传统的内容(html),层叠样式(css),行为动作(js)进行分离,这种分离仅仅是把三个不同的技术进行了物理上的分离,进行分开管理,如果从另一个视觉角度上讲,并没有实现高内聚的特点
既然前端本身就是页面的展示,那么把js和css放在一起,也是一种细粒度的组合,css也可以和Js一样,通过模块化的形式嵌入到js里面去
CSS modules很好的解决了样式冲突,利用了分而治之的理念,在如今组件化开发大行其道上,同样css也在不断的进化,如同js一样,也有变量,函数等具备Js一样的活力,那么在React中是怎么实现样式的模块化的?
通过单独的*.css文件定义组件的样式,并且通过clssName指定他们,有什么不好的?
在JSX上进行事件的监听绑定,通过on*EventType只针对原生的HTML标签起作用的,如果是自定义的组件,是不起作用的,有什么好的解决办法?
样式化组件的魅力(特点)
那么本节就是你想要知道的
React中组件形式
关于React中定义组件的形式,有如下几种方式,其中前两个在之前的学习当中,相信你已经很熟悉了的,如果不清楚,可以查看前面的内容的
类class声明的组件(类组件/容器组件)
函数式声明的组件(函数组件/无状态组件/UI组件)
样式化组件(styled-components)
本节主要讲的就是样式化组件,给一个React组件添加样式,有哪些方式?下面一起来看看的
行内样式 VS 外部样式
想要给React组件添加样式,常见的方式有
在JSX上添加style属性定义行内样式
通过import关键字引入外部样式
像如下所示,在JSX上添加样式: 下面的代码是用class类组件声明了一个Header组件,这个组件返回了一个button按钮,给这个按钮通过style添加了一些样式
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
class Header extends Component {
render(){
return (
<Fragment>
<button style = {
{
width: '100px', height: '40px', borderRadius: '3px', outline: 'none', outline: 'none', border: 'none', cursor: 'pointer', background: '#abcdef', color: '#fff'}}>button按钮</button>
</Fragment>
);
}
}
const container = document.getElementById('root');
ReactDOM.render(<Header />, container);
对于上面的行内样式,也可以把它定义成一个对象Object的方式去定义样式,与下面是等价的
class Header extends Component {
render(){
const btnStyle = {
width: '100px',
height: '40px',
borderRadius: '3px',
outline: 'none',
border: 'none',
cursor: 'pointer',
background: '#abcdef',
color: '#fff'
}
return (
<Fragment>
<button style = {
btnStyle }>button按钮</button>
</Fragment>
);
}
}
虽然这样也是在JS中写css样式,但是管理起来并不方便,很多时候,我们是用clssName的方式去定义样式的 ,按照我们熟悉的方式,就是把样式文件命名成*.css,然后通过import的方式给引入进去
import "./style.css";
对于样式名,有时候,对于各个不同的组件的className有可能会一样,如果是这样的话,后面引入的样式名会覆盖前面的,这样的话显然不是我们想要的结果了
那有什么好的解决办法?
在React中有css-in-js,它是一种模式,这个css由js生成而不是在外部文件中定义,是CSS Modules,主要是借助第三方库生成随机类名称的方式来建立一种局部类名的方式
这种css-in-js的第三方模块有很多:可以访问:https://github.com/MicheleBertoli/css-in-js
今天的主要学习的是github上star数最多的,styled-components
使用styled-components的好处是:它可以让组件自己的样式对自己生效,不是全局生效,做到互不干扰
首先你得通过npm或者cnpm进行安装styled-components模块
npm install -S styed-components
在安装完后,在使用styled-components的文件内,通过import的方式引入该模块
如下代码所示: 在文件的上方引入styled-components,实例化了一个styled对象,通过给styled对象下添加你想要的html元素,利用了Es6中的一个模板字符串,反引号
import React, { Fragment, Component } from 'react';
import ReactDOM from 'react-dom';
import styled from "styled-components"; // 引入styled-components库,实例化styled对象
// 声明样式ButtonA组件,通过styled对象进行创建,注意styled.html元素,后面是反引号
const ButtonA = styled.button`
width: 100px;
height: 40px;
border-radius: 3px;
outline: none;
border: none;
cursor: pointer;
background: #abcdef;
color: #fff;
`;
// 样式化声明ButtonB组件
const ButtonB = styled.button`
background: red;
color: #fff;
width: 100px;
height: 40px;
border-radius: 3px;
outline: none;
border: none;
cursor: pointer;
`;
class Header extends Component {
render(){
return (
<Fragment>
<ButtonA>按钮A</ButtonA>
<ButtonB>按钮B</ButtonB>
</Fragment>
);
}
}
const container = document.getElementById('root');
ReactDOM.render(<Header />, container);
这是