以下是 Spectre.Console 的核心功能示例,涵盖最常用的输出和交互场景:
1. 基础富文本输出

using Spectre.Console;
// 使用 Markup 语法(类似 BBCode)
AnsiConsole.Markup("[bold green]成功![/] 文件已保存。\n");
AnsiConsole.Markup("[red]错误:[/] 无法连接到服务器。\n");
// 混合样式
AnsiConsole.Markup("[underline blue]https://example.com[/]\n");
// 自动换行写
AnsiConsole.Write(new Panel("[yellow]警告[/] 磁盘空间不足")
.Header("系统通知")
.Border(BoxBorder.Rounded));2. 表格

var table = new Table();
table.AddColumn("[u]ID[/]");
table.AddColumn(new TableColumn("[u]名称[/]").Centered());
table.AddColumn("[u]状态[/]");
table.AddRow("1", "订单服务", "[green]运行中[/]");
table.AddRow("2", "支付网关", "[red]离线[/]");
table.AddRow("3", "消息队列", "[yellow]警告[/]");
AnsiConsole.Write(table);3. 进度条 / 状态指示


// 带进度条的循环任务
await AnsiConsole.Progress()
.StartAsync(async ctx =>
{
var task1 = ctx.AddTask("[green]下载文件[/]", maxValue: 100);
var task2 = ctx.AddTask("[green]处理数据[/]", maxValue: 100);
while (!ctx.IsFinished)
{
task1.Increment(1.5);
task2.Increment(0.8);
await Task.Delay(50);
}
});
// 不确定时长的旋转状态
await AnsiConsole.Status()
.StartAsync("正在连接...", async ctx =>
{
await Task.Delay(3000); // 模拟工作
AnsiConsole.MarkupLine("[green]连接成功![/]");
});4. 交互式提示

// 确认
if (AnsiConsole.Confirm("是否继续安装?"))
{
// 执行安装
}
// 文本输入(带验证)
var name = AnsiConsole.Prompt(
new TextPrompt<string>("请输入用户名:")
.ValidationErrorMessage("[red]用户名不能为空[/]")
.Validate(input => !string.IsNullOrWhiteSpace(input)));
// 选择列表
var fruit = AnsiConsole.Prompt(
new SelectionPrompt<string>()
.Title("请选择最喜欢的水果")
.AddChoices(new[] { "苹果", "香蕉", "橙子", "葡萄" }));
AnsiConsole.MarkupLine($"你选择了:[green]{fruit}[/]");
// 多选
var colors = AnsiConsole.Prompt(
new MultiSelectionPrompt<string>()
.Title("请选择颜色")
.AddChoices(new[] { "红色", "绿色", "蓝色", "黄色" }));5. 树形结构

var root = new Tree("[yellow]项目结构[/]");
var src = root.AddNode("src");
src.AddNode("Program.cs");
src.AddNode("Services");
src.AddNode("Models");
var tests = root.AddNode("tests");
tests.AddNode("UnitTests");
AnsiConsole.Write(root);6. 布局 / 网格

var layout = new Layout("Root")
.SplitColumns(
new Layout("Left").Size(30),
new Layout("Right")
.SplitRows(
new Layout("Top"),
new Layout("Bottom")));
layout["Left"].Update(new Panel("导航栏"));
layout["Top"].Update(new Panel("主内容区"));
layout["Bottom"].Update(new Panel("日志输出"));
AnsiConsole.Write(layout);7. 实时更新

var table = new Table().AddColumn("Time").AddColumn("Message");
table.AddRow("10:00", "系统启动");
await AnsiConsole.Live(table)
.StartAsync(async ctx =>
{
for (int i = 1; i <= 5; i++)
{
await Task.Delay(1000);
table.AddRow($"10:0{i}", $"事件 {i}");
ctx.Refresh(); // 刷新显示
}
});8. 带样式的异常显示

try
{
throw new InvalidOperationException("操作失败");
}
catch (Exception ex)
{
AnsiConsole.WriteException(ex, ExceptionFormats.ShortenPaths);
}9. 日历

var calendar = new Calendar(2026, 4);
calendar.AddCalendarEvent(2026, 4, 22); // 标记日期
calendar.HighlightStyle(Style.Parse("yellow bold"));
AnsiConsole.Write(calendar);10. 条形图 / 柱状图

AnsiConsole.Write(new BarChart()
.Width(60)
.Label("[green bold]项目进度[/]")
.CenterLabel()
.AddItem("后端", 80, Color.Green)
.AddItem("前端", 65, Color.Blue)
.AddItem("测试", 40, Color.Red));11. 分解图

AnsiConsole.Write(new BreakdownChart()
.Width(60)
.AddItem("CPU", 45, Color.Red)
.AddItem("内存", 30, Color.Blue)
.AddItem("磁盘", 25, Color.Green));12. 规则线

AnsiConsole.Write(new Rule("[red]警告区域[/]").RuleStyle("red").LeftJustified());
AnsiConsole.WriteLine("内容");
AnsiConsole.Write(new Rule().RuleStyle("green"));13. 文本样式

// 大字标题
AnsiConsole.Write(new FigletText("Hello").Color(Color.Green));
// Emoji
AnsiConsole.Markup(":check_mark_button: 成功 :cross_mark: 失败");14. 网格

var grid = new Grid();
grid.AddColumn(new GridColumn().NoWrap().PadRight(4));
grid.AddColumn();
grid.AddRow("[b]名称[/]", "Spectre.Console");
grid.AddRow("[b]版本[/]", "0.49.1");
grid.AddRow("[b]许可[/]", "MIT");
AnsiConsole.Write(grid);将 closeOnConfirm 设置为 false,需要关闭时调用 this.close();
例:
var $promt = $('#my-prompt').modal({
relatedTarget: this,
closeOnConfirm: false,
closeOnCancel: false,
onConfirm: function (e) {
if (!e.data) {
alert('输入点东西吧!')
} else {
alert('输入了');
this.close();
}
},
onCancel: function (e) {
alert('不想说!');
}
});
uni-app 的 input,当 type = "text" 时,设置 confirm-type = "next" 可以提供键盘的“下一项”,通过 @confirm 触发设置下一个文本框的焦点,即可实现只操作键盘即可完成表单填写。
我们以从 a 组件跳转到 b 组件为例:
<input v-model="a" type="text" confirm-type="next" @confirm="moveNext('b')" />uni-app 的组件只有属性和事件,不提供方法,那么我们只能设置提供了 focus 属性的组件的焦点。
<input v-model="b" :focus="focusList['b']" />moveNext() 方法实现:
moveNext(dom){
this.focusList[dom] = true;
}当然 focusList 必须先定义并初始化,否则设置 focus 为 true 将失效:
data() {
return {
a: '',
b: '',
focusList: {
b: false
}
}
}几个注意点:
confirm-type = "next" 仅支持微信小程序
“下一项”按钮效果是一次性的,使用一次后再次在 a 上触摸“下一项”将不再跳转到 b,即使在 moveNext() 中先设置为 false 再设置为 true 也没用
其它组件也可以通过自带的方法实现跳转到带 focus 属性的组件(如在 picker 的 @change 中设置 this.focusList['b'] = true)
限制于 confirm-type = "next" 只当 type = "text" 时有效,因此非文本键盘(如数字键盘)就不能提供“下一项”功能
textarea 组件的右下角始终是“换行”,由其右上角的“完成”按钮来实现“下一项”功能
textarea 组件在“下一项”跳转过程中,组件可能会被 tabBar 遮挡(几率很大)
方法:
alert,对话框,OK按钮
confirm,对话框,OK和Cancel按钮
prompt,对话框,可输入
close,关闭当前浏览器窗口
navigate,在当前窗口中导航到指定的URL资源
setInterval,设置每隔一定时间调用指定程序代码,毫秒,setInterval("Func()",5000)
setTimeout,设置经过一定时间后执行一次指定程序代码,毫秒,setTimeout("Func()",5000)
clearInterval,
clearTimeout,
moveTo,将浏览器窗口移动到屏幕上的某个位置
resizeTo,改变浏览器窗口的大小
open,打开一个新窗口 window.open("abc.html","_blank","top=0,left=0,width=100,height=200,toolbar=no");
showModalDialog产生一个模态对话框
showModelessDialog产生一个非模态对话框窗口
属性:
closed
opener
defaultstatus
status
screenTop
screenLeft
事件:
onload,onunload,onmouseover,...
对象属性:
location对象:设置和返回当前网页的URL信息。
载入一个新的网页:window.location.href="http://g.cn";
刷新当前页:window.location.reload();
event对象:获取和设置当前事件的有关信息。
altKey属性,用于检测事件发生时Alt键是否被按下
ctrlKey。。。
shiftKey...
screenX,screenY设置和返回鼠标相对屏幕顶点的x,y坐标
offsetX,offsetY设置和返回鼠标相对事件源顶点的x,y坐标
x,y 设置和返回鼠标相对事件源的父元素顶点x,y坐标
returnValue设置和返回事件的返回值,一般情况下设置为false
cancelBubble设置和返回当前事件是否继续向下传递
srcElement设置和返回事件源对象
keyCode设置和返回键盘按下或弹起时的键的unicode码
button检索鼠标动作使用的是哪个按键,1左鍵,2右键,3左右同时
function window_onkeypress()
{
// alert(window.event.keyCode);
if(window.event.keyCode==27)
{
window.close();
}
}