组件工坊:Reflex 组件库 100 例
·
课程概览
布局
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
排版
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
表单
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
数据展示
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
展开与切换
·
Tabs
·
Accordion
·
Segmented Control
浮层
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
动态渲染
·
Cond
·
Match
·
Foreach
·
Auto Scroll
媒体
·
Image
·
Audio
·
Video
表格与数据网格
·
Table
·
Data Table
·
Data Editor
图表
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
图表部件
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
其他图表库
·
Plotly
·
Pyplot
HTML 元素
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
其他工具
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
rx.flex官方文档
工坊订单
请把多张商品卡片横向排开,屏幕变窄时,放不下的卡片自动换到下一行。
rx.flex 是用 CSS 弹性盒(flexbox)把子元素排成一行的盒子。横向还是纵向、是否换行、如何对齐、剩余空间怎么分,几个属性就能定下来。默认是横向(row)且不换行。这是做响应式页面时最常用的布局。
rx.flex(
rx.card("Card 1"),
rx.card("Card 2"),
rx.card("Card 3"),
rx.card("Card 4"),
rx.card("Card 5"),
spacing="2",
width="100%",
)只有 Card 2 个子更高,所以 align 的差别看得很清楚。把 wrap 改成 wrap,放不下的卡片就会换到下一行。
试着改属性
direction
align
justify
wrap
spacing
rx.flex(
rx.card("Card 1", width="30%"),
rx.card("Card 2", width="30%", height="5rem"),
rx.card("Card 3", width="30%"),
rx.card("Card 4", width="30%"),
rx.card("Card 5", width="30%"),
direction="row",
align="stretch",
justify="start",
wrap="nowrap",
spacing="2",
width="100%",
min_height="14rem",
padding="12px",
border="1px dashed var(--gray-7)",
border_radius="8px",
)| 属性 | 取值 | 默认值 | 用途 |
|---|---|---|---|
direction | "row" "column" "row-reverse" "column-reverse" | "row" | 子元素的排列方向(主轴) |
align | "start" "center" "end" "baseline" "stretch" | "stretch" | 与主轴垂直的轴(交叉轴)上的对齐 |
justify | "start" "center" "end" "between" | "start" | 主轴方向的对齐。between 让两端贴边、中间均分 |
wrap | "nowrap" "wrap" "wrap-reverse" | "nowrap" | 放不下时是否换行 |
spacing | "0" ~ "9" | 无 | 子元素间距(Radix 间距等级)。也可以直接用 CSS gap |
as_child | True / False | False | 不渲染 Flex,而是渲染子元素并合并属性 |
所有属性都可以用 rx.breakpoints(...) 按屏幕宽度给出不同的值。已安装的 0.10 的属性说明把 align 和 justify 的轴写反了,但实际行为与上表一致。
子元素太多、一行放不下时,默认(nowrap)会把子元素压缩。设置 wrap="wrap" 后,子元素保持尺寸,换到下一行。像官方文档那样写 CSS 属性 flex_wrap="wrap",效果也一样。
rx.flex(
rx.foreach(
rx.Var.range(10),
lambda i: rx.card(f"Card {i + 1}", width="16%"),
),
spacing="2",
wrap="wrap",
width="100%",
)direction="column" 时从上往下堆叠。加上 -reverse 后顺序会倒过来。适合代码顺序不变、只改显示顺序的场合。
rx.flex(
rx.flex(rx.card("Card 1"), rx.card("Card 2"), rx.card("Card 3"), spacing="2", direction="column"),
rx.flex(rx.card("Card 1"), rx.card("Card 2"), rx.card("Card 3"), spacing="2", direction="column-reverse"),
rx.flex(rx.card("Card 1"), rx.card("Card 2"), rx.card("Card 3"), spacing="2", direction="row-reverse"),
spacing="6",
wrap="wrap",
)给 rx.breakpoints 传入从 initial(最窄的屏幕)到 xs sm md lg xl 的值,属性就会随屏幕宽度变化。Radix 属性的断点宽度为:xs 520px、sm 768px、md 1024px、lg 1280px、xl 1640px。下面的例子在窄屏上纵向排列,在 sm 及以上横向排列。试着调整浏览器窗口的宽度。
rx.flex(
rx.card("Card 1", flex_grow="1"),
rx.card("Card 2", flex_grow="1"),
rx.card("Card 3", flex_grow="1"),
direction=rx.breakpoints(initial="column", sm="row"),
spacing=rx.breakpoints(initial="2", md="4"),
width="100%",
)Flex 里的子元素用三个 CSS 属性调整尺寸。尺寸调整总是沿着主轴进行(row 时是宽度,column 时是高度)。
flex_basis:合适的基础尺寸。没有就用 width(或 height),再没有就用内容尺寸。flex_grow(默认 "0"):为 "0" 时不会超过基础尺寸;为 "1" 时占据剩余空间。flex_shrink(默认 "1"):为 "0" 时不会小于基础尺寸。用滑块缩小外层 Flex 的宽度试试。flex_shrink=0 的盒子守住 100px,其余的先缩小。
class FlexSizeHintState(rx.State):
width_pct: int = 100
@rx.event
def set_width_pct(self, value: list[float]):
self.width_pct = int(value[0])
@rx.var
def width_css(self) -> str:
return f"{self.width_pct}%"
def flex_border_box(label, **props):
return rx.box(label, border="1px solid var(--gray-10)", border_radius="2px", padding="4px", font_size="12px", **props)
rx.box(
rx.flex(
flex_border_box("flex_shrink=0", flex_shrink="0", width="100px"),
flex_border_box("flex_shrink=1", flex_shrink="1", width="200px"),
flex_border_box("flex_grow=0", flex_grow="0"),
flex_border_box("flex_grow=1", flex_grow="1"),
width=FlexSizeHintState.width_css,
spacing="2",
margin_bottom="16px",
),
rx.slider(
min=0,
max=100,
value=[FlexSizeHintState.width_pct],
on_change=FlexSizeHintState.set_width_pct,
),
width="100%",
)每张卡片用 flex_basis="140px" 定下基础宽度,再用 flex_grow="1" 分享剩余空间。有了 wrap="wrap",窄屏上卡片会换到下一行。
Mug
$12
Plate
$12
Bowl
$12
Vase
$12
Cup
$12
Tray
$12
rx.flex(
rx.foreach(
["Mug", "Plate", "Bowl", "Vase", "Cup", "Tray"],
lambda name: rx.card(
rx.text(name, weight="bold"),
rx.text("$12", size="2", color="var(--gray-11)"),
flex_basis="140px",
flex_grow="1",
),
),
spacing="3",
wrap="wrap",
width="100%",
)工坊笔记
rx.flex 把子元素排成一行。默认 row、nowrap。
direction 定主轴,justify 是主轴对齐,align 是交叉轴对齐。
wrap="wrap" 时放不下的子元素换到下一行。spacing "0"~"9" 控制间距。
子元素的尺寸用 flex_basis·flex_grow·flex_shrink 调整。
用 rx.breakpoints(initial=…, sm=…) 按屏幕宽度给出不同的值。
订阅新课时和新课程通知
本课程新增课时或推出后续课程时,我们会发邮件通知你。
问答
关于本课有任何疑问都可以在这里留言。所有语言版本页面的提问会汇集在一起。