第七周
date
May 24, 2022
slug
week-7
tags
Website
summary
type
Post
status
Published
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>
);
}

styled-component/macro
我叒换手机了!
由于手机又丢了,所有有了这篇 我的一加8T装了啥? 的 Blog
购买 Theine.app
这是一个让 Mac 不休眠的状态栏小工具。刚好遇到有限时优惠只要 $0.99,设计很精美的 App
购买安卓App 带壳截图Pro

终于等到了 Github Codespaces 试用资格


收到邮件后就迫不及待的试用了一下。所有 VS Code 的设置都自动同步过来,不需要任何的配置就有一个最熟悉的编辑器,和之前使用较多的 Gitpod 相比开发体验还是有提升。期待云 IDE、开发环境发展得更加成熟。
用 Raycast 替代 Manico 的部分功能


用 Manico 来帮助我使用快捷键快速的打开常用软件,就这个功能来说在 Raycast 中给 App 配置 Hotkey 也可以完成相同的事情。但 Manico 的作者都维护了它近 10 年了
了解 tRPC
最近在读 ‣ 代码时看到有使用 tPRC 这个库,大概过了一下官方的介绍。和 GraphQL 的要解决的问题有一些相似。