反馈 · 9 / 21
Dialog st-dialog
模态对话框:headline / 默认 / actions 三插槽,open 是运行时状态,页面里用 sync:open 双向绑定。auto-close 允许点击遮罩或 Escape 关闭并派发 close;面板用原生 ::part(panel) 定制。
基础用法与 sync:open
用一个布尔 data 控制开合:按钮把 dlgBasic 置 true,对话框内部按钮置 false。没有 auto-close 时,点击遮罩与 Escape 都不会关闭,只能由外部状态或按钮关闭。
sync:open示例代码
<st-button on:click="dlgOpen = true">打开对话框</st-button>
<st-dialog sync:open="dlgOpen">
<h2 slot="headline">基础对话框</h2>
<p>没有 auto-close:点遮罩与 Escape 都不会关闭。</p>
<div slot="actions">
<st-button variant="text" on:click="dlgOpen = false">关闭</st-button>
</div>
</st-dialog>
<script>
export default async () => ({
data: { dlgOpen: false },
});
</script>
auto-close 与 close 事件
设置 auto-close 后,点击遮罩或按 Escape 会关闭对话框、把 sync:open 绑定的数据回写为 false,并派发 close 事件。close 只在交互关闭时派发;用按钮改数据关闭不会触发。
auto-close / on:close示例代码(关闭计数)
<st-dialog sync:open="dlgAuto" auto-close on:close="onAutoClose">
<h2 slot="headline">auto-close</h2>
<p>点击遮罩或按 Escape 关闭,close 事件会冒泡到页面。</p>
</st-dialog>
<script>
export default async () => ({
data: { dlgAuto: false, closeCount: 0 },
proto: {
onAutoClose() {
this.closeCount += 1;
},
},
});
</script>
用 ::part(panel) 定制面板
遮罩宿主铺满视口,面板在 shadow 内,用浏览器原生的 ::part(panel) 覆盖宽度、圆角、高度与底色;字号类属性可直接写在宿主 style 上,面板会等比缩放。下面的样式只写在本页 shadow 内。
::part(panel)示例代码
<style>
st-dialog.wide::part(panel) {
width: min(46em, 100%);
border-radius: 1em;
}
st-dialog.full::part(panel) {
width: 100%; height: 100%; max-height: 100%;
border-radius: 0; background: var(--md-sys-color-surface);
}
</style>
<st-dialog class="wide" sync:open="dlgWide" auto-close>...</st-dialog>
<st-dialog class="full" sync:open="dlgFull" auto-close>...</st-dialog>
<st-dialog sync:open="dlgSmall" auto-close style="font-size: 12px;">...</st-dialog>
headline / actions 插槽
三个插槽各自独立:headline 放标题、默认插槽放正文、actions 放按钮。哪个插槽没有内容,对应区块就自动隐藏——不需要写空 div 占位。
slots示例代码
<st-dialog sync:open="dlgSlotPlain" auto-close>
<h2 slot="headline">只有标题与正文</h2>
<p>没有 actions 插槽内容,底部操作区不会出现。</p>
</st-dialog>
<st-dialog sync:open="dlgSlotNoHead" auto-close>
<p>没有 headline,标题区块自动隐藏。</p>
<div slot="actions">
<st-button variant="text" on:click="dlgSlotNoHead = false">知道了</st-button>
</div>
</st-dialog>
命令式 alert / confirm / prompt
基于 st-dialog 的即用即毁工具,返回 Promise:alert 确认 true / 关闭 null;confirm 确认 true / 取消 false / 关闭 null;prompt 确认返回字符串 / 其余 null。遮罩与 Escape 都按取消处理,文本自动转义。
window.__site.alert / confirm / prompt示例代码
import alert from "/packages/dialog/alert.js";
import confirm from "/packages/dialog/confirm.js";
import prompt from "/packages/dialog/prompt.js";
const ok = await alert({ title: "操作成功", message: "密码已重置。", ok: "知道了" });
const sure = await confirm({ title: "确认删除", message: "不可撤销", yes: "删除", cancel: "取消", color: "error" });
const name = await prompt({ title: "重命名", message: "输入新的名称", placeholder: "新名称" });
对话框里的表单与焦点
打开时焦点自动移入面板容器,Tab 可逐个进入内部控件。下面把 st-input 放进正文并用 sync:value 绑定,保存时把值写回页面数据;关闭后数据仍保留。
form + sync:value示例代码
<st-dialog sync:open="dlgForm" auto-close>
<h2 slot="headline">新建项目</h2>
<st-input sync:value="projectName" placeholder="项目名称"></st-input>
<div slot="actions">
<st-button variant="text" on:click="dlgForm = false">取消</st-button>
<st-button on:click="saveProject">保存</st-button>
</div>
</st-dialog>
<script>
export default async () => ({
data: { dlgForm: false, projectName: "", savedName: "(无)" },
proto: {
saveProject() {
this.savedName = this.projectName || "(空)";
this.dlgForm = false;
},
},
});
</script>
属性
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
open | 运行时状态(ofa data) | false | 显示状态;页面里用 sync:open="key" 双向绑定 |
auto-close | boolean | 无 | 允许点击遮罩 / Escape 关闭,并派发 close |
插槽 / 事件 / 注意
- 插槽:
headline(建议放 h2)、默认(正文,超高时内部滚动)、actions(右对齐横排);空区块自动隐藏。 - 事件:
close(bubbles + composed),只在遮罩 / Escape 交互关闭时派发;外部改数据关闭不派发。 - 面板:
::part(panel)覆盖宽度 / 圆角 / 底色;默认宽min(34.29em, 100%)、padding1.43em、圆角1.714em。 - 焦点:打开时移入面板容器并在内部循环(焦点陷阱),关闭后归还打开元素;Escape / 遮罩仅在 auto-close 时生效,多个对话框叠加时 Escape 只关最上层;打开期间锁定背景滚动。
- 注意:对话框别放进设置过 transform / filter 的祖先,否则 fixed 遮罩会错位;宿主的 z-index 是 1000。