服务
NetNexus UI 提供无需在模板中预放置组件的通知服务和确认弹窗服务。两者通过 netnexus-ui/services 导出,也可从根入口导入。
样式准备
已使用完整组件样式时无需重复引入:
js
import 'netnexus-ui/style.css';只使用服务时,服务样式仍会引用主题 Token,因此要同时引入:
js
import 'netnexus-ui/theme.css';
import 'netnexus-ui/services.css';Notification
基础用法
js
import { notificationService } from 'netnexus-ui/services';
notificationService.success('保存成功');
notificationService.warning('连接不稳定', 5);
notificationService.error(new Error('保存失败'));持续显示加载通知,并在任务结束时主动关闭:
js
import { notificationService } from 'netnexus-ui/services';
async function save() {
const closeLoading = notificationService.loading('正在保存…');
try {
await saveToServer();
closeLoading();
notificationService.success('保存成功');
} catch (error) {
closeLoading();
notificationService.error(error);
}
}API
五种通知方法都使用相同的参数顺序:
text
notificationService.success(content, duration?, onClose?)
notificationService.error(content, duration?, onClose?)
notificationService.warning(content, duration?, onClose?)
notificationService.info(content, duration?, onClose?)
notificationService.loading(content, duration?, onClose?)| 方法 | 默认持续时间 | ARIA live 行为 |
|---|---|---|
success | 3 秒 | role="status"、polite |
error | 3 秒 | role="alert"、assertive |
warning | 3 秒 | role="alert"、assertive |
info | 3 秒 | role="status"、polite |
loading | 不自动关闭 | role="status"、polite |
参数说明:
| 参数 | 说明 |
|---|---|
content | Error 使用其 message;null/undefined 变为空字符串;其他值通过 String() 转换 |
duration | 单位为秒;数值大于 0 时自动关闭,0 或负数时持续显示 |
onClose | 通知退出动画结束并移除 DOM 后调用 |
每个方法返回一个关闭函数。在浏览器中,该函数还带有相同值的 id 和 key:
js
const close = notificationService.info('后台任务已开始', 0, () => {
console.log('通知已关闭');
});
console.log(close.id);
console.log(close.key);
// 下面两种方式都能关闭该通知。
close();
// notificationService.destroy(close.key);批量关闭:
js
notificationService.destroy();destroy(activeKey) 会关闭对应的活动通知。当前实现中,如果传入的 key 不存在,也会继续关闭全部通知;不要把未经确认的 key 直接传给 destroy()。
通知内容使用 textContent 写入,不会解析 HTML,也不接受 VNode。关闭按钮始终可以手动关闭通知。
ConfirmDialog
基础用法
js
import { confirmDialogService } from 'netnexus-ui/services';
function removeProject(project) {
confirmDialogService.confirm({
title: '删除项目',
content: `确定删除“${project.name}”吗?`,
okText: '删除',
cancelText: '保留',
okType: 'danger',
async onOk() {
await deleteProject(project.id);
},
onCancel() {
console.log('用户取消删除');
}
});
}onOk 返回 Promise 时,确定按钮会进入“处理中...”状态并阻止重复操作。Promise 完成后弹窗关闭;若 onOk 抛错或拒绝,当前实现会输出警告并保持弹窗打开。
选项
| 选项 | 类型 | 默认行为 |
|---|---|---|
title | string | 确认操作 |
content | string | () => VNodeChild | 空内容 |
okText | string | 确定 |
cancelText | string | 取消 |
okType | 'default' | 'danger' | 非 danger 时使用主按钮样式 |
maskClosable | boolean | false,点击遮罩不关闭 |
onOk | () => void | Promise<void> | 确定时调用 |
onCancel | () => void | Promise<void> | 取消按钮、关闭按钮、Escape 或可关闭遮罩触发 |
返回的 handle 可跳过回调直接销毁弹窗:
js
const dialog = confirmDialogService.confirm({
title: '等待确认',
content: '这个弹窗会在 10 秒后自动移除。'
});
window.setTimeout(() => dialog.destroy(), 10_000);移除所有由服务创建的确认弹窗:
js
confirmDialogService.destroyAll();VNode 内容与文本输入
content 函数可以返回 Vue VNode。服务还提供一个轻量的原生输入框 VNode 工厂:
vue
<script setup>
import { h, ref } from 'vue';
import { confirmDialogService } from 'netnexus-ui/services';
const projectName = ref('');
function openCreateDialog() {
confirmDialogService.confirm({
title: '创建项目',
content: () =>
h('div', [
h('p', '请输入项目名称:'),
confirmDialogService.textInput({
value: projectName.value,
maxlength: 40,
placeholder: '例如:gateway',
'onUpdate:value': value => {
projectName.value = value;
},
onPressEnter: event => {
console.log('按下 Enter', event);
}
})
]),
async onOk() {
await createProject(projectName.value);
projectName.value = '';
}
});
}
</script>
<template>
<NnButton @click="openCreateDialog">创建项目</NnButton>
</template>textInput() 不是公开组件,而是返回原生 <input> VNode 的辅助函数。当前运行时读取以下字段:
| 字段 | 行为 |
|---|---|
value | 输入框当前值 |
maxlength | 原生最大长度属性 |
placeholder | 原生占位文本 |
onUpdate:value | 每次原生 input 事件后接收字符串 |
onPressEnter | 按 Enter 时接收键盘事件 |
其 TypeScript 参数当前声明为 Record<string, unknown>,不会为以上字段提供精确自动补全。
交互与无障碍
- 弹窗使用
role="dialog"和aria-modal="true",标题与正文会关联到对应的 ARIA 属性。 - 打开时优先聚焦
.nn-confirm-input,否则聚焦第一个可交互元素或弹窗本身。 - Tab 和 Shift+Tab 会被限制在最上层确认弹窗内。
- 只有最上层弹窗响应 Escape;关闭后会在适当时恢复之前的焦点。
- 弹窗存在期间会锁定
body滚动,并对多个服务弹窗共享计数。 onCancel抛错时会记录警告,但弹窗仍会关闭。
已知边界
- 两项服务都依赖
document。服务端或其他无 DOM 环境中不会渲染:确认框返回空操作 handle;通知会立即调用onClose并返回空操作函数。 - 通知类型声明要求关闭函数具有
id/key,但无 DOM 分支返回的空操作函数没有这两个属性。 - 通知只支持字符串化内容,没有 VNode、HTML、位置、最大数量或按 key 更新 API。
- 确认弹窗通过独立的
createApp()挂载,不继承主应用的provide、插件或全局组件上下文。VNode 内容应使用已导入的组件或原生节点。 - 确认弹窗的默认可见文案为中文;当前没有全局 locale 配置。
- 手动
destroy()和destroyAll()不调用onOk或onCancel。
