第七周
date
May 24, 2022
tags
Website
summary
type
Post
status
Published
slug
week-7
styled-components 记录
最近看 CSS for JS 课程,看到作者分享使用 styled-components 的一些技巧,感觉很有用,所以记录总结一下。
Demystifying styled-components The styled-components Happy Path
基础的处理逻辑
当我们使用 styled-components 生成一个组件的时候会发生下面代码这几件事:
const styled = (Tag) => (styles) => {
return function NewComponent(props) {
// 生成唯一 class 名
const uniqueClassName = comeUpWithUniqueName(styles);
// 加工 style 字符串
const processedStyles = runStylesThroughStylis(styles);
// style 字符注入 css 文件
createAndInjectCSSClass(uniqueClassName, styles);
// 新的 className 和组件本身的 className 组合
const combinedClasses =
[uniqueClassName, props.className].join(' ');
// 绑定 className
return <Tag className={combinedClasses} {...props} />
}
}
模板字符使用 props 后会生成两个份不一样的 className 和 CSS
因为 props 对象里的值是暂时无法确定的,必须等到运行后才能确定
/* before */
const ContentImage = styled.img`
display: block;
margin-bottom: 8px;
width: 100%;
max-width: ${p => p.maxWidth};
`;
render(
<>
<ContentImage
alt="A running shoe with pink laces and a rainbow decal"
src="/images/shoe.png"
maxWidth="200px"
/>
<ContentImage
alt="A close-up shot of the same running shoe"
src="/images/shoe-closeup.png"
/>
</>
)
/* after */
<style>
.JDSLg {
display: block;
margin-bottom: 8px;
width: 100%;
max-width: 200px;
}
.eXyedY {
display: block;
margin-bottom: 8px;
width: 100%;
}
</style>
<img
alt="A running shoe with pink laces and a rainbow decal"
src="/images/shoe.png"
class="sc-bdnxRM JDSLg"
/>
<img
alt="A close-up shot of the same running shoe"
src="/images/shoe-closeup.png"
class="sc-bdnxRM eXyedY"
/>
使用 CSS 变量会生成更少的代码,减少摩擦
例如下面的
var(—max-width)
,配合 style
对象参数,它们会共享一个 className 和 CSS 代码。/* before */
const ContentImage = styled.img`
display: block;
margin-bottom: 8px;
width: 100%;
max-width: var(--max-width);
`;
render(
<>
<ContentImage
alt="A running shoe with pink laces and a rainbow decal"
src="/images/shoe.png"
style={{
'--max-width': '200px',
}}
/>
<ContentImage
alt="A close-up shot of the same running shoe"
src="/images/shoe-closeup.png"
/>
</>
)
/* after */
<style>
.JDSLg {
display: block;
margin-bottom: 8px;
width: 100%;
max-width: var(--max-width);
}
</style>
<img
alt="A running shoe with pink laces and a rainbow decal"
src="/images/shoe.png"
class="sc-bdnxRM JDSLg"
style="--max-width: 200px"
/>
<img
alt="A close-up shot of the same running shoe"
src="/images/shoe-closeup.png"
class="sc-bdnxRM JDSLg"
/>
组件单一样式控制
有两种适用的场景,一个场景是两个组件都是通用组件,会频繁适用,与业务逻辑不强关联
// Aside.js
const Aside = ({ children }) => { /* Omitted for brevity */ }
// Export this wrapper
export const Wrapper = styled.aside`
/* styles */
`;
export default Aside;
// TextLink.js
import { Wrapper as AsideWrapper } from '../Aside'
const TextLink = styled.a`
color: var(--color-primary);
font-weight: var(--font-weight-medium);
${AsideWrapper} & {
color: var(--color-text);
font-weight: var(--font-weight-bold);
}
`;
// render after
.TextLink-abc123 {
color: var(--color-primary);
font-weight: var(--font-weight-medium);
}
.Aside-Wrapper-def789 .TextLink-abc123 {
color: var(--color-text);
font-weight: var(--font-weight-bold);
}
还有一种是在某种业务情况下使用,与当前的业务有较强的关联
import TextLink from '../TextLink';
import { Wrapper as AsideWrapper } from '../Aside'
const HalloweenTextLink = styled(TextLink)`
--color-primary: orange;
font-family: 'Spooky Font', cursive;
`;
// render css
.TextLink-abc123 {
color: var(--color-primary);
font-weight: var(--font-weight-medium);
}
.HalloweenTextLink-edf321 {
--color-primary: orange;
}
<div
class="TextLink-abc123 HalloweenTextLink-edf321"
>
hello!
</div>
as 语义化
Extending Styles
不要让包裹的标签全是
div
,可以根据语义使用 as
指定包裹的标签// `level` is a number from 1 to 6, mapping to h1-h6
function Heading({ level, children }) {
const tag = `h${level}`;
return (
<Wrapper as={tag}>
{children}
</Wrapper>
);
}
// The `h2` down here doesn't really matter,
// since it'll always get overwritten!
const Wrapper = styled.h2`
/* Stuff */
`;
function LinkButton({ href, children, ...delegated }) {
const tag = typeof href === 'string'
? 'a'
: 'button';
return (
<Wrapper as={tag} href={href} {...delegated}>
{children}
</Wrapper>
);
}
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2F14e4d555-e9d2-439f-8807-7736878a6283%2FUntitled.png%3Fid%3D96524f47-98de-454b-84ba-f0065f2e56c7%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3Dg0a_r4-qG_uuxdjDF-Obluvr-I88QOZNj7fiYcYtlwA?table=block&id=96524f47-98de-454b-84ba-f0065f2e56c7&cache=v2)
styled-component/macro
我叒换手机了!
由于手机又丢了,所有有了这篇 我的一加8T装了啥? 的 Blog
购买 Theine.app
这是一个让 Mac 不休眠的状态栏小工具。刚好遇到有限时优惠只要 $0.99,设计很精美的 App
购买安卓App 带壳截图Pro
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2Fc7d11bd1-6249-40fb-8e4f-e7fb1fd736a5%2FShell_20220527-194702-321.png%3Fid%3D5b9d8c46-7f4b-44bd-8113-c45663c86304%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3DJ2ah8BqMGQhTXU4ja_dbG1iyHEPsnxGm7tMGFIQARJA?table=block&id=5b9d8c46-7f4b-44bd-8113-c45663c86304&cache=v2)
终于等到了 Github Codespaces 试用资格
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2Feab0b31e-092f-46e1-b2cb-8e37dde5a2e6%2FUntitled.png%3Fid%3D096a8f12-99f1-48f3-a266-6ef1cc236186%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3D43U3dtErSfr1B_cvzHfCAabo0_ujgIrSUReBhUxHdwo?table=block&id=096a8f12-99f1-48f3-a266-6ef1cc236186&cache=v2)
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2Fa83b271b-f041-424f-b0c2-35917103dfb0%2FUntitled.png%3Fid%3Ddc9efd23-7d20-499c-b785-eee85bae1a7c%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3DCXofTjEekDqIx2FAJsBBo_bbQLF9NV4DqF4SAERAXQQ?table=block&id=dc9efd23-7d20-499c-b785-eee85bae1a7c&cache=v2)
收到邮件后就迫不及待的试用了一下。所有 VS Code 的设置都自动同步过来,不需要任何的配置就有一个最熟悉的编辑器,和之前使用较多的 Gitpod 相比开发体验还是有提升。期待云 IDE、开发环境发展得更加成熟。
用 Raycast 替代 Manico 的部分功能
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2Fae036294-87e7-44b2-a61b-ecdf1f9a650a%2FUntitled.png%3Fid%3Dd0201f82-b011-4e78-8120-cfddab7ae74b%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3DR46hRZt9MmHfD5kEpps_3TjUZcqezRP1-v9O72qOZpI?table=block&id=d0201f82-b011-4e78-8120-cfddab7ae74b&cache=v2)
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2F0f418bfe-525d-42fe-968c-235a38fc88d5%2FUntitled.png%3Fid%3D703c03d8-0667-43b1-b6be-8a981fa86e27%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3DqYKwa0ljgFWCgrUeu1FNLIhac3OR0GjGtlYERIDM7yk?table=block&id=703c03d8-0667-43b1-b6be-8a981fa86e27&cache=v2)
用 Manico 来帮助我使用快捷键快速的打开常用软件,就这个功能来说在 Raycast 中给 App 配置 Hotkey 也可以完成相同的事情。但 Manico 的作者都维护了它近 10 年了
了解 tRPC
最近在读 ‣ 代码时看到有使用 tPRC 这个库,大概过了一下官方的介绍。和 GraphQL 的要解决的问题有一些相似。
Simple, strong types.
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2F91735e6e-abba-45da-8487-1a530eb0ec04%2Fb83f0d0d-f038-4ace-96b2-c1aabbd8493c%2FScreenshot_20221204-173402_YouTube.png%3Fid%3D3d6d0dfd-e042-44aa-8a2e-ffb3f1228f3b%26table%3Dblock%26spaceId%3D91735e6e-abba-45da-8487-1a530eb0ec04%26expirationTimestamp%3D1718157600000%26signature%3DBUCBzBnlvXFO9sCtvoYpEnS8D6qXfbdduAO9TcJTyIA?table=block&id=3d6d0dfd-e042-44aa-8a2e-ffb3f1228f3b&cache=v2)