Rust的CSS-in-JS库styled_jsx的使用:为Rust项目提供高效的组件级CSS样式封装方案
Rust的CSS-in-JS库styled_jsx的使用:为Rust项目提供高效的组件级CSS样式封装方案
安装
在项目目录中运行以下Cargo命令:
cargo add styled_jsx
或者在Cargo.toml中添加以下行:
styled_jsx = "0.97.0"
基本使用
styled_jsx是一个为Rust项目提供的CSS-in-JS解决方案,它允许你在组件级别封装CSS样式,类似于React中的styled-components。以下是一个基本示例:
use styled_jsx::styled_jsx;
use yew::prelude::*;
#[function_component]
pub fn StyledButton() -> Html {
html! {
<>
<button class="styled-button">
{"点击我"}
</button>
{styled_jsx!(
r#"
.styled-button {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
transition: background-color 0.3s;
}
.styled-button:hover {
background-color: #45a049;
}
"#
)}
</>
}
}
完整示例
下面是一个更完整的组件示例,展示了如何使用styled_jsx来创建带有动态样式的组件:
use styled_jsx::styled_jsx;
use yew::prelude::*;
#[derive(Properties, PartialEq)]
pub Props {
#[prop_or_default]
pub primary: bool,
#[prop_or_default]
pub size: String,
}
#[function_component]
pub Button(Props { primary, size }) -> Html {
let button_class = if *primary { "primary" } else { "secondary" };
let size_class = match size.as_str() {
"small" => "small",
"large" => "large",
_ => "medium",
};
html! {
<>
<button class={classes!("button", button_class, size_class)}>
{"按钮"}
</button>
{styled_jsx!(
r#"
.button {
font-family: 'Arial', sans-serif;
border: none;
border-radius: 3px;
cursor: pointer;
display: inline-block;
line-height: 1;
transition: all 0.2s;
}
.button.primary {
color: white;
background-color: #1ea7fd;
}
.button.secondary {
color: #333;
background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
}
.button.small {
font-size: 12px;
padding: 10px 16px;
}
.button.medium {
font-size: 14px;
padding: 11px 20px;
}
.button.large {
font-size: 16px;
padding: 12px 24px;
}
.button:hover {
opacity: 0.9;
}
"#
)}
</>
}
}
特性
- 组件级样式封装:样式与组件紧密绑定,避免全局CSS污染
- 自动前缀:自动添加浏览器前缀,确保跨浏览器兼容性
- 动态样式:可以根据组件props动态生成样式
- 高效编译:通过SWC进行高效编译
文档
更多详细用法请参考官方文档
项目信息
- 版本:0.97.0
- 许可证:Apache-2.0
- 大小:67.1 KiB
1 回复
Rust的CSS-in-JS库styled_jsx使用指南
styled_jsx
是一个为Rust项目设计的CSS-in-JS库,它提供了组件级的CSS样式封装方案,让开发者能够在Rust代码中直接编写CSS样式,实现样式与组件的紧密耦合。
主要特性
- 组件级样式作用域:自动为样式添加唯一标识,避免全局污染
- CSS-in-JS语法:直接在Rust代码中编写CSS
- 高性能:编译时处理,运行时零开销
- 支持Sass类语法:嵌套规则、变量等现代CSS特性
安装方法
在Cargo.toml
中添加依赖:
[dependencies]
styled_jsx = "0.4"
基本使用方法
1. 定义样式组件
use styled_jsx::styled;
let button = styled! {
button {
padding: 8px 16px;
background: #0070f3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background: #0061d5;
}
}
};
2. 使用样式组件
use yew::prelude::*;
#[function_component]
fn MyComponent() -> Html {
html! {
<div>
<button class={button}>
{"点击我"}
</button>
</div>
}
}
高级用法
动态样式
use styled_jsx::styled;
fn get_dynamic_button(primary: bool) -> String {
styled! {
button {
padding: 8px 16px;
background: ${if primary { "#0070f3" } else { "#eaeaea" }};
color: ${if primary { "white" } else { "#333" }};
border: none;
border-radius: 4px;
}
}
}
全局样式
use styled_jsx::global;
global! {
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
a {
color: #0070f3;
text-decoration: none;
}
}
样式继承
use styled_jsx::styled;
let base_button = styled! {
button {
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
};
let primary_button = styled! {
${base_button} {
background: #0070f3;
color: white;
&:hover {
background: #0061d5;
}
}
};
完整示例代码
下面是一个完整的Yew组件示例,展示了styled_jsx的各种用法:
use yew::prelude::*;
use styled_jsx::{styled, global};
// 定义全局样式
global! {
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
}
// 基础按钮样式
fn base_button_style() -> String {
styled! {
button {
padding: 10px 20px;
border-radius: 5px;
font-size: 1rem;
cursor: pointer;
transition: all 0.2s ease;
}
}
}
// 主要按钮组件
#[function_component]
fn PrimaryButton() -> Html {
let style = styled! {
${base_button_style()} {
background: #0070f3;
color: white;
border: none;
&:hover {
background: #0061d5;
}
}
};
html! {
<button class={style}>
{"主要按钮"}
</button>
}
}
// 次要按钮组件
#[function_component]
fn SecondaryButton() -> Html {
let style = styled! {
${base_button_style()} {
background: #eaeaea;
color: #333;
border: 1px solid #ccc;
&:hover {
background: #ddd;
}
}
};
html! {
<button class={style}>
{"次要按钮"}
</button>
}
}
// 带动态样式的卡片组件
#[function_component]
fn CardComponent() -> Html {
let is_highlighted = true;
let card_style = styled! {
div {
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
background: ${if is_highlighted { "#fff8e1" } else { "white" }};
margin-bottom: 20px;
}
};
let title_style = styled! {
h2 {
color: #333;
margin-top: 0;
margin-bottom: 10px;
}
};
html! {
<div class={card_style}>
<h2 class={title_style}>{"卡片标题"}</h2>
<p>{"这是一个使用styled_jsx的卡片组件示例"}</p>
<div style="margin-top: 15px;">
<PrimaryButton />
<SecondaryButton />
</div>
</div>
}
}
// 主应用组件
#[function_component]
fn App() -> Html {
let container_style = styled! {
div {
max-width: 800px;
margin: 0 auto;
padding: 40px 20px;
}
};
html! {
<div class={container_style}>
<h1>{"styled_jsx示例应用"}</h1>
<CardComponent />
</div>
}
}
fn main() {
yew::Renderer::<App>::new().render();
}
构建配置
在项目的build.rs
文件中添加以下配置以优化样式输出:
fn main() {
styled_jsx::configure()
.minify(true) // 生产环境压缩CSS
.write_to_file("static/styles.css") // 将CSS提取到单独文件
.setup();
}
注意事项
- 样式类名在开发模式下是有意义的名称,在生产模式下会被压缩成短名称
- 动态样式在每次渲染时都会生成新的CSS,应谨慎使用
- 对于大型项目,建议将基础样式提取到单独的文件中
- 样式继承功能可以帮助减少重复代码,提高可维护性