CSS In JS 编写方案
认识CSS In JS
官方文档也有提到过CSS In JS这种方案:
“CSS-In-JS” 是指一种模式,其中 CSS 由 JavaScript 生成而不是在外部文件中定义;
在传统的前端开发中,我们通常会将结构(HTML)、样式(CSS)、逻辑(JavaScript)进行分离。
但是在前面的学习中,我们就提到过,React的思想中认为逻辑本身和UI是无法分离的,所以才会有了JSX的语法。
事实上CSS-In-JS的模式就是一种将样式(CSS)也写入到JavaScript中的方式,并且可以方便的使用JavaScript的状态;
所以React有被人称之为 All In JS;
Stop using CSS In JavaScript for web development, 有一篇文章说到在web开发中, 停止使用CSS In JS, 文章地址给到大家, 有兴趣可以阅读一下
https://hackernoon.com/stop-using-css-in-javascript-for-web-development-fa32fb873dcc
批评声音虽然有,但是在我看来很多优秀的CSS-In-JS的库依然非常强大、方便:
CSS-In-JS通过JavaScript来为CSS赋予一些能力,包括类似于CSS预处理器一样的样式嵌套、函数定义、逻辑复用、动态修改状态等等;
CSS In JS的库
目前可以说styled-components
依然是社区最流行的CSS-In-JS库,所以我们以styled–components的讲解为主;
安装styled–components: npm i styled-components
标签模板字符串
在正式讲解styled–components库之前, 我先来给大家回顾一下ES6模板字符串的另外一种用法(会的可以直接跳过)
ES6中增加了模板字符串的语法,这个对于很多人来说都会使用, 这里我就不再过多赘述, 但是模板字符串还有另外一种用法:标签模板字符串(Tagged Template Literals)。
function foo(...args) {
console.log(args)
}
// 正常情况下调用函数的方式
foo("Hello World")
function foo(...args) {
console.log(args)
}
// 标签模板字符串调用
foo`Hello World`
function foo(...args) {
console.log(args)
}
const name = "chenyq"
const age = 18
// 标签模板字符串调用
foo`Hello ${name}, my age is ${age}`
在styled component中,就是通过这种方式来解析模块字符串,最终生成我们想要的样式的
styled基本使用
styled–components的本质是通过函数的调用,最终创建出一个新的组件:
styled–components会给该class添加相关的样式;
- 例如我们有下面这样一个结构
export class App extends PureComponent {
render() {
return (
<div className='app'>
<h2 className='title'>我是标题</h2>
<ul className='content'>
<li className='item'>我是内容1</li>
<li className='item'>我是内容2</li>
<li className='item'>我是内容3</li>
<li className='item'>我是内容4</li>
<li className='item'>我是内容5</li>
</ul>
</div>
)
}
}
- 在一个单独是
style.js
文件中, 我们通过styled–components库创建出来一个组件, 代替最外层的div, 创建完成后使用需要导入 - 这里可以使用VS Code插件
vscode-styled-components
, 安装后就会有代码提示和高亮显示
// style.js文件
import styled from "styled-components"
// 调用div会返回一个组件, 该组件会会渲染成一个div元素, 并且可以添加样式
export const AppWrapper = styled.div`
color: skyblue;
.title {
font-size: 30px;
}
.content {
font-size: 12px;
}
`
// 导入创建的组件
import { AppWrapper } from './style'
export class App extends PureComponent {
render() {
return (
<AppWrapper>
<h2 className='title'>我是标题</h2>
<ul className='content'>
<li className='item'>我是内容1</li>
<li className='item'>我是内容2</li>
<li className='item'>我是内容3</li>
<li className='item'>我是内容4</li>
<li className='item'>我是内容5</li>
</ul>
</AppWrapper>
)
}
}
export const AppWrapper = styled.div`
color: skyblue;
.title {
font-size: 30px;
}
.content {
font-size: 12px;
.item:nth-child(1) {
color: red;
}
.item {
border: 1px solid #aaa;
&:hover {
color: green;
}
}
}
`
如果我们觉得上面css样式过多或者嵌套层级过深的话, 我们是可以根据自己的需求将子元素单独抽离到一个样式组件中
import styled from "styled-components"
export const AppWrapper = styled.div`
color: skyblue;
.title {
font-size: 30px;
}
`
// 抽离content
export const ContentWrapper = styled.ul`
font-size: 12px;
.item:nth-child(1) {
color: red;
}
.item {
border: 1px solid #aaa;
&:hover {
color: green;
}
}
`
import { AppWrapper, ContentWrapper } from './style'
export class App extends PureComponent {
render() {
return (
<AppWrapper>
<h2 className='title'>我是标题</h2>
<ContentWrapper>
<li className='item'>我是内容1</li>
<li className='item'>我是内容2</li>
<li className='item'>我是内容3</li>
<li className='item'>我是内容4</li>
<li className='item'>我是内容5</li>
</ContentWrapper>
</AppWrapper>
)
}
}
props和attrs属性
我们知道, React在的less/css方案中, 是不方便引入js中的数据的, 而CSS In JS方案解决了这个问题
import { AppWrapper } from './style'
export class App extends PureComponent {
constructor() {
super()
this.state = {
size: 30,
color: "skyblue"
}
}
render() {
const { size, color } = this.state
return (
// 传递props属性
<AppWrapper size={size} color={color} >
<h2 className='title'>我是标题</h2>
<p className='content'>我是内容哈哈哈</p>
</AppWrapper>
)
}
}
export const AppWrapper = styled.div`
.title {
/* 插值函数 */
font-size: ${props => props.size}px;
}
.content {
/* 插值函数 */
color: ${props => props.color};
}
`
render() {
const { size, color } = this.state
return (
// 传递props属性
<AppWrapper size={size} color={color} >
<h2 className='title'>我是标题</h2>
<p className='content'>我是内容哈哈哈</p>
{/* 动态修改样式 */}
<button onClick={() => this.setState({ size: size + 2 })}>修改字体大小</button>
</AppWrapper>
)
}
attrs属性可以接受一个对象, 在对象中设置默认值, 但是设置时需要判断是否有传入样式, 否则传入的样式就不会再生效; 也可以接受一个函数, 该函数会接收props参数, 且该函数需要返回一个对象
需要注意的是, 对象中的属性名不能和props里面的变量名相同, 否则会产生递归, 例如这种写法就是
错误
的color: props => props.color || "red",
// 接收函数的话, 函数需要返回一个对象
export const AppWrapper = styled.div.attrs(props => ({
// 判断传入的样式是否有值
tColor: props.color || "red",
tSize: props.size || 12
}))`
.title {
font-size: ${props => props.tSize}px;
}
.content {
color: ${props => props.tColor};
}
`
styled高级特性
styled设置主题
export const primaryColor = "#f1f1f1"
export const secondColor = "#ccc"
export const smallSize = "12px"
export const largeSize = "20px"
import styled from "styled-components";
import * as vers from "./style/variables"
export const AppWrapper = styled.div`
.content {
/* 使用主题颜色和字体 */
font-size: ${vers.largeSize};
color: ${vers.primaryColor};
}
`
支持样式的继承(了解)
const MyButton = styled.button`
padding: 8px 30px;
border-radius: 20px;
`
// 会将MyButton中的属性继承过来
const MyButtonEx = styled(MyButton)`
color: red;
`
原文地址:https://blog.csdn.net/m0_71485750/article/details/126715988
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_7021.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!