emotion的安装 yarn add @emotion/react @emotion/styled
emotion的基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import styled from "@emotion/styled"; // 引入emotion import logo from "assets/logo.svg"; // 引入图片 import left from "assets/left.svg"; import right from "assets/right.svg"; export const UnauthenticatedApp = () => { const [isRegister, setIsRegister] = useState(false); return ( <Container> <Header></Header> <ShadowCard> {isRegister ? ( <RegisterScreen></RegisterScreen> ) : ( <LoginScreen></LoginScreen> )} <Divider></Divider> <a onClick={() => setIsRegister(!isRegister)}> 切换到{isRegister ? "登录" : "注册"} </a> </ShadowCard> </Container> ); }; // 每个style都是一个组件 const Header = styled.header` background: url(${logo}) no-repeat center; padding: 5rem 0; background-size: 8rem; width: 100%; `; const ShadowCard = styled(Card)`// 非html原生标签要用括号,比如组件库和React.component width: 40rem; min-height: 56rem; padding: 3.2rem 4rem; border-radius: 0.3rem; box-sizing: border-box; box-shadow: rgba(0, 0, 0, 0.1) 0 0 10px; text-align: center; `; // 原生html const Container = styled.div` display: flex; flex-direction: column; align-items: center; min-height: 100vh; justify-content: center; `;
emotion中使用grid和flex布局 grid
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const Container = styled.div` min-height: 100vh; display: grid; grid-template-rows: 6rem 1fr 6rem; grid-template-columns: 20rem 1fr 20rem; grid-template-areas: "header header header" "nav main aside" "footer footer footer" `; // 这里value没有引号 const Header = styled.header` grid-area: header; `; const Nav = styled.nav` grid-area: nav; `; const Main = styled.main` grid-area: main; `; const Aside = styled.aside` grid-area: aside; `; const Footer = styled.footer` grid-area: footer; `;
flex
:
1 2 3 4 5 6 7 8 9 10 11 12 const Header = styled.header` grid-area: header; display: flex; flex-flow: row nowrap; justify-content: space-between; align-items: center; `; const HeaderLeft = styled.div` display: flex; flex-flow: row nowrap; `;
flex和grid使用场景?
1维布局用flex,二维布局用grid。
从内容出发:先有一组内容(数量一般不固定),希望他们均匀分布在容器中,由内容的大小决定占据的空间–flex。
从布局触发:先规划网格(数量一般固定),然后再把元素往里填充。–grid
用emotion封装一个flex布局 style.component
创建出来的是是一个React.component
对象,那么当然可以接受参数(毕竟组件实质上也只是一个函数),将style
写成一个组件的形式,听起来很厉害
在src下的componets文件里新建一个lib.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import styled from "@emotion/styled" ;export const Row = styled.div<{ between?: boolean ; gap?: number | boolean ; marginBottom?: number ; }>` display: flex; flex-flow: row nowrap; align-items: center; justify-content: ${(props) => (props.between ? "space-between" : undefined )} ; margin-bottom: ${(props) => props.marginBottom + "rem" } ; > * { // 这里代表所有子元素 margin-top: 0 !important; margin-bottom: 0 !important; margin-right: ${(props) => typeof props.gap === "number" ? props.gap + "rem" : props.gap ? "2rem" : undefined } ; } ` ;
在项目中引用并使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { Row } from "components/lib"; const Header = styled(Row)``; const HeaderLeft = styled(Row)``; <Header between={true}> // 在这里传递参数,是不是很像组件! <HeaderLeft gap={true}> <h3>logo</h3> <h3>我的</h3> <h3>项目</h3> </HeaderLeft> <HeaderRight> <button onClick={() => logout()}>登出</button> </HeaderRight> </Header>
emotion在行内样式中使用 1 2 3 4 5 6 /** @jsxRuntime classic */ /** @jsx jsx */ // 第一行表示使用旧版传统模式手动导入运行时 // 第二行表示指明下一行为运行时的导入 <Form css={{ marginBottom: "2rem" }} layout={"inline"}>
不是很推荐使用 css props ,可以选择使用外链 css 文件或 @emotion/styled
的 styled-components 方案,都是很不错的选择。