2.2.1 卡片组件(ui.card)
卡片是NiceGui中用于信息分组展示的容器组件,它将相关内容组织在一个有视觉边界的区域内,具有以下特征:
视觉层次
通过阴影、边框和间距建立内容层级关系
内容封装
将相关元素(文本、图片、按钮等)组合为逻辑单元
交互容器
可作为整体添加点击等交互事件
基础卡片应用
该元素基于 Quasar 框架的 QCard 组件实现,提供一个带有阴影效果的容器。
注意:与原生 QCard 不同,本组件默认自带内边距(padding),且不会隐藏嵌套元素的外部边框和阴影。如需使用原生 QCard 的紧凑样式,请调用 tight() 方法。版本 2.0.0 更新: 不再隐藏嵌套元素的外部边框和阴影。
from nicegui import ui
with ui.card().classes("w-64"):
ui.label("基础卡片").classes("text-lg font-bold")
ui.separator()
ui.label("卡片内容区域")
with ui.row().classes("justify-end"):
ui.button("确定")
ui.button("取消")
ui.run()
卡片布局参数
参数说明: align_items:卡片内部元素的对齐方式(可选值:"start"、"end"、"center"、"baseline" 或 "stretch";默认值:None)
2.2.2 高级卡片功能
可折叠卡片
with ui.card().classes("w-full") as card:
header = ui.row().classes("items-center justify-between")
with header:
ui.label("可折叠内容").classes("text-lg")
toggle_btn = ui.button(icon="expand_more")
content = ui.column().classes("pt-2")
with content:
ui.label("详细内容...")
# 初始折叠状态
content.visible = False
deftoggle_content():
content.visible = not content.visible
toggle_btn._props['icon'] = 'expand_less'if content.visible else'expand_more'
toggle_btn.on("click", toggle_content)
带图片卡片
with ui.card().classes("w-80"):
ui.image("https://picsum.photos/300/200").classes("rounded-t")
with ui.column().classes("p-4 gap-2"):
ui.label("风景图片").classes("text-xl font-bold")
ui.separator()
ui.label("拍摄时间: 2023-05-01")
ui.label("地点: 阿尔卑斯山脉")
with ui.row().classes("justify-between items-center"):
ui.rating().props("size=24px")
ui.button("查看大图", icon="zoom_in")
2.2.3 分割线组件(ui.separator)
基础分割线应用
ui.label("上方内容")
ui.separator()
ui.label("下方内容")
示例2:
with ui.card().classes('w-full'):
ui.label('用户信息').classes('text-h5')
ui.separator().props('inset') # 缩进式分割线
with ui.row():
ui.avatar('A').props('size=lg')
ui.label('Admin User').classes('self-center text-lg')
ui.separator().props('inset')
with ui.grid(columns=2):
ui.label('注册时间:')
ui.label('2023-05-15')
ui.label('最后登录:')
ui.label('2024-02-20')
分割线样式定制
ui.separator().classes("my-4") # 垂直间距
ui.separator().style("border-top: 2px dashed #e2e8f0") # 虚线样式
ui.separator().props("vertical").classes("h-8 mx-4") # 垂直分割线
2.2.4 组合应用
信息展示面板
with ui.card().classes("w-96 shadow-lg"):
# 标题区域
with ui.row().classes("items-center gap-4 p-4"):
ui.icon("person", size="lg", color="primary")
ui.label("用户信息").classes("text-2xl")
ui.separator()
# 内容区域
with ui.column().classes("p-4 gap-3"):
info = {
"姓名": "张三",
"职位": "前端工程师",
"部门": "技术部",
"入职时间": "2020-06-01"
}
for k, v in info.items():
with ui.row().classes("items-center justify-between"):
ui.label(k).classes("text-gray-500")
ui.label(v).classes("font-medium")
# 操作区域
ui.separator()
with ui.row().classes("justify-end p-2 gap-2"):
ui.button("编辑", icon="edit")
ui.button("更多", icon="more_vert")
2.2.5 响应式卡片布局
自适应网格布局
with ui.grid(columns=2).classes("w-full gap-4 sm:grid-cols-3 lg:grid-cols-4"):
for i in range(8):
with ui.card().classes("hover:shadow-xl transition-all"):
ui.label(f"卡片 {i+1}").classes("text-center")
ui.separator()
ui.image(f"https://picsum.photos/200/150?random={i}")
卡片悬停效果
with ui.card().classes("""
w-64
transform
transition-all
hover:-translate-y-2
hover:shadow-xl
cursor-pointer
"""):
ui.label("悬停效果卡片")
ui.separator()
ui.label("鼠标悬停查看动画效果")
2.2.6 实践指南
卡片设计原则
性能优化技巧
避免过度嵌套卡片
对静态卡片使用cache=True
图片使用懒加载
ui.image(...).props("loading=lazy")
2.2.7 常见问题解决
问题1:卡片布局错位
解决方案:
# 使用固定宽高比
with ui.card().classes("aspect-[4/3] w-64"):
ui.image(...).classes("h-full object-cover")
问题2:分割线颜色不一致
调试方法:
ui.separator().style("border-color: red !important") # 强制测试颜色
问题3:卡片点击事件冲突
事件处理方案:
with ui.card().on("click", handle_card_click):
# 内部按钮需要阻止事件冒泡
ui.button("内部按钮").on("click", lambda e: e.stopPropagation())
2.2.8 实战案例:电商商品卡片
from nicegui import ui
import random
products = [
{
"name": "无线耳机",
"price": 299,
"image": "https://picsum.photos/300/200?headphones",
"stock": random.randint(0, 50)
},
{
"name": "智能手表",
"price": 599,
"image": "https://picsum.photos/300/200?watch",
"stock": random.randint(0, 50)
}
]
for product in products:
with ui.card().classes("w-72 relative"):
# 库存标签
if product['stock'] == 0:
with ui.row().classes("absolute top-2 right-2 bg-red-500 text-white px-2 py-1 rounded"):
ui.icon("warning")
ui.label("售罄")
# 图片区域
ui.image(product['image']).classes("h-48 object-cover")
# 信息区域
with ui.column().classes("p-4 gap-2"):
ui.label(product['name']).classes("text-xl font-bold")
ui.separator()
with ui.row().classes("items-center justify-between"):
ui.label(f"¥{product['price']}").classes("text-red-500 text-lg")
ui.label(f"库存: {product['stock']}").classes("text-gray-500")
# 操作按钮
with ui.row().classes("justify-end gap-2"):
ui.button(icon="shopping_cart", color="primary")
ui.button(icon="favorite_border")
ui.run()
2.2.9 扩展应用:设置面板布局
with ui.card().classes("w-full max-w-2xl"):
ui.label("系统设置").classes("text-2xl p-4")
# 账户设置
with ui.column().classes("w-full p-4"):
ui.label("账户设置").classes("text-lg font-medium")
ui.separator()
with ui.grid(columns=2).classes("gap-4 w-full"):
ui.input("用户名")
ui.input("邮箱").props("type=email")
ui.input("密码").props("type=password")
# 界面设置
with ui.column().classes("w-full p-4"):
ui.label("界面设置").classes("text-lg font-medium")
ui.separator()
with ui.row().classes("items-center gap-4"):
ui.toggle(["浅色", "深色"], value="浅色")
ui.select(["中文", "English"], value="中文")
# 提交区域
ui.separator()
with ui.row().classes("justify-end p-4"):
ui.button("取消", color="gray")
ui.button("保存设置", color="primary")
更新日期:2025-05-28
交流讨论:欢迎在评论区留言!
重要提示:本文主要是记录自己的学习与实践过程,所提内容或者观点仅代表个人意见,只是我以为的,不代表完全正确,不喜请勿关注。
领取专属 10元无门槛券
私享最新 技术干货