组件工坊: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
工坊订单
请不用设计系统,只用纯 HTML 亲手做一张带关闭按钮和链接的小公告卡片。
rx.el 原样包含了 Web 开发中使用的 HTML 元素。rx.el.div 就是 <div>,rx.el.button 就是 <button>。
与基于 Radix 的 rx.button 不同,它们没有 variant·size 这类外观属性,出来的是完全没有样式的状态。
本站启用了 Tailwind 的基础重置(preflight),所以连按钮的边框和输入框的线条都被清掉了。
A plain paragraph.
rx.el.div(
rx.el.p("A plain paragraph."),
rx.el.button("A plain button"),
rx.el.input(placeholder="A plain input"),
)外观要用样式属性(把 CSS 属性名写成下划线形式的关键字参数)直接加上。改改值,看看这个光秃秃的按钮会怎样变化。
试着改属性
label
background
color
padding
radius
weight
disabled
rx.el.button(
"Buy now",
background="#4f46e5",
color="white",
padding="8px 16px",
border_radius="6px",
font_weight="600",
disabled=False,
cursor="pointer",
)| 属性 | 取值 | 默认值 | 用途 |
|---|---|---|---|
CSS 属性(padding, color …) | CSS 值 | 无 | 用关键字参数直接加样式 |
class_name | 类名字符串 | 无 | Tailwind 之类的 CSS 类 |
id title hidden role tab_index lang dir | 字符串·bool·int | 无 | 所有元素通用的 HTML 属性 |
custom_attrs | dict | 无 | aria-*、data-* 这类名字里带 - 的属性 |
type (button) | "submit" "reset" "button" | 浏览器:"submit" | 在表单里点击时要做的事 |
type (input) | "text" "email" "range" "date" … 共 22 种 | "text" | 输入框的类型 |
value / on_change (input) | 字符串·数字 / 事件 | 无 | 受控输入框。default_value 是非受控 |
href target (a) | URL / "_blank" … | 无 | 链接地址与打开位置 |
on_click on_key_down … | 事件处理器 | 无 | 所有元素都有的基本事件 |
关键字样式属性、style 字典、class_name 的 CSS 类。三种可以混用。
使用 rx.color("indigo", 3) 这样的主题色,在深色模式下颜色也会相应变化。
rx.el.div(
rx.el.div(
"Style props",
padding="12px",
border=f"1px solid {rx.color('indigo', 7)}",
border_radius="8px",
background=rx.color("indigo", 3),
),
rx.el.div(
"style dict",
style={"padding": "12px", "border": "1px dashed gray", "border_radius": "8px"},
),
rx.el.div(
"Tailwind classes",
class_name="p-3 rounded-lg border-2 border-dotted font-semibold",
),
display="flex",
gap="12px",
flex_wrap="wrap",
)title 是鼠标悬停时出现的原生提示,hidden 是隐藏,dir 是文字方向,tab_index 是 Tab 键的顺序。
aria-label、data-kind 这类名字里有连字符的属性,用 custom_attrs 传入。
Right to left
rx.el.div(
rx.el.span("Hover me", title="A native tooltip", text_decoration="underline dotted"),
rx.el.span("You cannot see me", hidden=True),
rx.el.p("Right to left", dir="rtl", lang="en"),
rx.el.div(
"Focus me with Tab",
tab_index=0,
role="note",
custom_attrs={"aria-label": "Demo note", "data-kind": "demo"},
padding="8px",
border="1px solid gray",
border_radius="6px",
),
display="flex",
flex_direction="column",
gap="8px",
)用 on_click 修改 State 这一点和 rx.button 一样。放在表单里时,type 很重要。
不指定时是浏览器默认的 "submit",一点就会提交表单,所以普通按钮要写 type="button"。
name·value 是提交时一并发送的值,form_action·form_method 这类 form_* 属性只针对这个按钮修改表单的设置。
class HtmlElButtonState(rx.State):
count: int = 0
@rx.event
def add_one(self):
self.count += 1
rx.el.div(
rx.el.button(
"Add one",
type="button",
on_click=HtmlElButtonState.add_one,
padding="6px 14px",
border="1px solid gray",
border_radius="6px",
cursor="pointer",
),
rx.el.button("Disabled", disabled=True, padding="6px 14px", border="1px solid gray", border_radius="6px", opacity="0.5"),
rx.el.span("Count: ", HtmlElButtonState.count),
display="flex",
gap="12px",
align_items="center",
)同时给 value 和 on_change,就成了由 State 掌管的受控输入框。rx.el.input 单独提供 on_change、on_key_down、on_key_up 事件。
on_key_down 会传入按下的键名,所以下面显示最后按下的键。type="range" 会变成滑块。
Hello, (last key: )
Level: 40
class HtmlElInputState(rx.State):
name: str = ""
level: int = 40
last_key: str = ""
@rx.event
def change_name(self, value: str):
self.name = value
@rx.event
def change_level(self, value: float):
self.level = int(value)
@rx.event
def remember_key(self, key: str):
self.last_key = key
rx.el.div(
rx.el.input(
type="text",
value=HtmlElInputState.name,
on_change=HtmlElInputState.change_name,
on_key_down=HtmlElInputState.remember_key,
placeholder="Your name",
max_length=20,
padding="6px 10px",
border="1px solid gray",
border_radius="6px",
),
rx.el.p("Hello, ", HtmlElInputState.name, " (last key: ", HtmlElInputState.last_key, ")"),
rx.el.input(
type="range",
min=0,
max=100,
step=5,
value=HtmlElInputState.level,
on_change=HtmlElInputState.change_level,
),
rx.el.p("Level: ", HtmlElInputState.level),
display="flex",
flex_direction="column",
gap="8px",
max_width="320px",
)只靠一个 type,就能变成日期、颜色、复选框、邮箱、数字输入框。不用 State、只给初始值时,用 default_value·default_checked。
required、min·max、pattern、max_length 这类校验属性会在提交表单时由浏览器检查。
rx.el.div(
rx.el.input(type="date"),
rx.el.input(type="color", default_value="#6e56cf"),
rx.el.label(rx.el.input(type="checkbox", default_checked=True), " Remember me"),
rx.el.input(type="email", placeholder="you@example.com", required=True, border="1px solid gray", padding="4px 8px"),
rx.el.input(type="number", min=1, max=9, default_value=3, border="1px solid gray", padding="4px 8px", width="80px"),
display="flex",
gap="12px",
flex_wrap="wrap",
align_items="center",
)p 是段落,独占一整行;span 是留在行内的片段。div 是没有语义的盒子,用来把任何东西包在一起。
A p is a block. A span stays inside the line.
rx.el.div(
rx.el.p(
"A p is a block. A ",
rx.el.span("span", color=rx.color("tomato", 11), font_weight="bold"),
" stays inside the line.",
),
rx.el.div("A div is a box with no meaning.", padding="8px", background=rx.color("gray", 3)),
)Reflex 0.10 的 rx.el.a 会渲染成 React Router 的 Link,href 在内部被转成 to。
所以 "/" 这类站内地址会在不重新加载页面的情况下跳转,外部地址则像普通链接一样打开。
想重新加载页面再跳转用 reload_document=True,想替换历史记录用 replace=True,过渡效果用 view_transition=True。download 让链接作为文件下载。
rx.el.div(
rx.el.a(
"Reflex docs (new tab)",
href="https://reflex.dev/docs/library/html/html/",
target="_blank",
rel="noopener noreferrer",
color=rx.color("indigo", 11),
text_decoration="underline",
),
rx.el.a("Home page", href="/", color=rx.color("indigo", 11), text_decoration="underline"),
display="flex",
gap="16px",
)rx.el 的元素有 100 多个。文本元素、文档结构、表单、媒体、表格、SVG 会在接下来的五个页面中分组介绍。
用 span 做徽章,用 p 写正文,用 a 和 button 实现操作,全部用样式属性来装饰。关闭后由 State 把卡片隐藏起来。
class HtmlElNoticeState(rx.State):
visible: bool = True
@rx.event
def dismiss(self):
self.visible = False
@rx.event
def show_again(self):
self.visible = True
rx.cond(
HtmlElNoticeState.visible,
rx.el.div(
rx.el.p(
rx.el.span(
"New",
background=rx.color("indigo", 9),
color="white",
padding="2px 8px",
border_radius="999px",
font_size="12px",
margin_right="8px",
),
"Version 2 is out.",
font_weight="600",
),
rx.el.p("Read what changed before you update.", color=rx.color("gray", 11), margin_y="6px"),
rx.el.div(
rx.el.a(
"Release notes",
href="https://reflex.dev/docs/",
target="_blank",
rel="noopener noreferrer",
color=rx.color("indigo", 11),
text_decoration="underline",
),
rx.el.button(
"Dismiss",
type="button",
on_click=HtmlElNoticeState.dismiss,
padding="4px 12px",
border=f"1px solid {rx.color('gray', 7)}",
border_radius="6px",
cursor="pointer",
),
display="flex",
gap="16px",
align_items="center",
),
padding="16px",
border=f"1px solid {rx.color('indigo', 6)}",
border_radius="10px",
background=rx.color("indigo", 2),
max_width="360px",
),
rx.el.button("Show again", on_click=HtmlElNoticeState.show_again, text_decoration="underline", cursor="pointer"),
)工坊笔记
rx.el.<标签> 就是原样的 HTML 元素,没有样式。外观用 CSS 关键字属性·style·class_name 加上。
title·hidden·dir·tab_index·role 是所有元素通用的。aria-*·data-* 用 custom_attrs。
表单里的 rx.el.button 默认是 submit。普通按钮写 type="button"。
rx.el.input 用 value + on_change 受控,用 default_value 非受控。on_key_down 传入按下的键。
0.10 的 rx.el.a 是 React Router Link:href 变成 to,在站内跳转时不重新加载。
订阅新课时和新课程通知
本课程新增课时或推出后续课程时,我们会发邮件通知你。
问答
关于本课有任何疑问都可以在这里留言。所有语言版本页面的提问会汇集在一起。