表单 · 7 / 21
Radio st-radio
单选按钮:用 name 作为分组键,在最近的同一容器内互斥;attr:checked 表示选中态,change 只在被点中的那一项派发。圆圈与间距全用 em,改 font-size 即等比缩放。
基础用法与同组互斥
同组选项写在同一个父容器里,name 相同的 st-radio 自动互斥。用 attr:checked 绑定数据、on:change 回写选中值,页面状态与组件选中态保持同一条链路。
LIVE
name + attr:checked示例代码(受控单选组)
<st-radio name="plan" attr:checked="plan === 'free'" on:change="plan = 'free'">免费版</st-radio>
<st-radio name="plan" attr:checked="plan === 'pro'" on:change="plan = 'pro'">专业版</st-radio>
<st-radio name="plan" attr:checked="plan === 'team'" on:change="plan = 'team'">团队版</st-radio>
<script>
export default async () => ({
data: { plan: "pro" },
});
</script>
change 事件与回显
change 是 composed 事件,会穿过 shadow 冒泡到页面;只有被用户点中的那一项派发,被取消的兄弟项不会派发。点击已选中的项也不会重复触发。
LIVE
on:change示例代码(事件回显)
<st-radio name="fruit" attr:checked="fruit === 'apple'" on:change="setFruit('apple')">苹果</st-radio>
<st-radio name="fruit" attr:checked="fruit === 'banana'" on:change="setFruit('banana')">香蕉</st-radio>
<script>
export default async () => ({
data: { fruit: "apple", fruitChanges: 0 },
proto: {
setFruit(value) {
this.fruit = value;
this.fruitChanges += 1;
},
},
});
</script>
disabled、color 与尺寸
disabled 会阻断点击和键盘并降到 0.38 透明度;color 接受 M3 角色名或 color 工具里的自定义变量名,只影响选中态的圆环与圆点。改宿主 font-size 即可整体等比缩放。
LIVE
disabled / color / font-size示例代码
<st-radio name="off" disabled checked>禁用 · 已选中</st-radio>
<st-radio name="color" color="error" checked>error</st-radio>
<st-radio name="color" color="success">success</st-radio>
<st-radio name="scale" style="font-size: 20px;">font-size: 20px</st-radio>
卡片式选项
把 st-radio 本身写成卡片:display:flex + width:100% + 原生 padding / border,组件的透明原生 input 会覆盖整张卡片,点标题、价格或留白都能选中。
LIVE
st-radio as card示例代码(整卡可点)
<st-radio name="plan" attr:checked="plan === 'team'" on:change="pick('team')"
style="display: flex; width: 100%; padding: 14px 16px; border: 1px solid var(--md-sys-color-outline-variant); border-radius: 14px;">
<span style="display: grid; gap: 2px; text-align: left;">
<strong>团队版</strong>
<span style="font-size: 11px;">¥25 / 人 / 月 · 无限项目</span>
</span>
</st-radio>
列表式选项
把一列 st-radio 直接放进带边框的原生 div,每一项 display:flex + width:100% 铺满整行,用 border-bottom 分隔。组内的互斥范围就是这个外层 div,不要再给每一行套独立 div。
LIVE
vertical list
导出格式:{{format}} · {{formatHint}}
示例代码(表单列表)
<div style="display: grid; border: 1px solid var(--md-sys-color-outline-variant); border-radius: 14px;">
<st-radio name="format" attr:checked="format === 'png'" on:change="format = 'png'"
style="display: flex; width: 100%; padding: 13px 16px; border-bottom: 1px solid var(--md-sys-color-outline-variant);">
PNG · 透明背景
</st-radio>
<st-radio name="format" attr:checked="format === 'jpg'" on:change="format = 'jpg'"
style="display: flex; width: 100%; padding: 13px 16px;">
JPG · 照片优先
</st-radio>
</div>
分组边界:同名不同容器
互斥范围是最近的 st-list / st-menu / fieldset / form / div / section。下面两个容器都用 name="doc-shared",但它们是两个独立组,各自保持一个选中项。需要联动时,请把选项放进同一个容器。
LIVE
grouping scope
容器 A
选项 A1
选项 A2
容器 B
选项 B1
选项 B2
A 与 B 互不影响;点 A2 只会取消 A1,B1 仍然选中。
示例代码(两个独立容器)
<div class="group-a">
<st-radio name="shared" checked>选项 A1</st-radio>
<st-radio name="shared">选项 A2</st-radio>
</div>
<div class="group-b">
<st-radio name="shared" checked>选项 B1</st-radio>
<st-radio name="shared">选项 B2</st-radio>
</div>
属性
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
name | string | 无 | 分组键:选中时取消同一树作用域内同 name 的其他 st-radio |
checked | boolean | 无 | 选中态;页面里用 attr:checked="expr" 绑定 |
disabled | boolean | 无 | 0.38 透明度、阻断点击与键盘 |
color | M3 角色名 / 自定义变量名 | 无 | 只影响选中态的圆环与圆点 |
插槽 / 事件 / 注意
- 插槽:默认插槽放标签文字;没有内容时标签区自动隐藏,可当作纯指示器。
- 事件:
change(bubbles + composed),仅被点中的那一项派发;被取消的兄弟项不派发。 - 键盘:Tab 聚焦、Space / Enter 选中;焦点环画在圆圈外圈。
- 尺寸:圆环
1.571em、圆点0.714em、标签间距0.857em,改font-size全部等比缩放。 - 分组按树作用域:原生 radio 的 name 分组不跨 shadow root,组件在同一 document / o-page shadow root 内手动互斥(不再要求同父容器)。