为了账号安全,请及时绑定邮箱和手机立即绑定

如何用JavaScript打造漂亮的终端界面(TUI)!

如果你也和我一样特别着迷于命令行界面和终端界面,这篇帖子就是为你写的!

可惜的是,在JavaScript中,没有一种内置的方法来构建漂亮的终端用户界面——至少我知道的没有!我自己也遇到了同样的问题,最终我决定移植了一个最令人惊艳的TUI库之一,即Lipgloss,由Charm团队开发。

你不相信我吗?你看看这个就知道了。

魅力 CLI Ligloss

真好看,对吧?

有个需要注意的地方:Lipgloss 是用 Go 语言编写的。虽然我通常使用 Go,但我最近需要写一个用 Node.js 的网页监控工具。我可不想放弃那些漂亮的界面,所以我把自己置于一个经典的 开发者挑战模式,这样。

你知道那些神奇的瞬间,当你沉浸在编码中时,突然有个意想不到的东西就这么顺利了?就这样,我将 Lipgloss 的一部分移植到了 WebAssembly(Wasm)上。就这样,charsm 诞生了。

charm是什么?

Charsm 是 Charm CLI + Wasm 的简称。超酷的,对吧?让我们来看看如何用它来构建酷炫的 TUI(文本用户界面),这些 TUI 是用 JavaScript 编写的。

……

开始入门

安装 charms 只需一条简单的 npm 命令:

npm install charsm
``` (安装名为charsm的npm包)

切换到全屏模式,退出全屏

此处为空

## 创建一个简单的表

首先,你需要在脚本中导入`charsm`并进行初始化。
import { initLip, Lipgloss } from "charsm";

// 异步初始化唇部模型
(async function () {
  // 获取初始化的唇部模型
  const ini = await initLip();
})();

全屏 退出全屏

`initLip`函数加载Wasm文件并为渲染做好准备。我们试着输出一个表格吧。
const rows = [
  ["中文", "您好", "你好"],
  ["日语", "こんにちは", "やあ"],
  ["阿拉伯语", "你好", "你好"],
  ["俄文", "Здравствуйте", "您好"],
  ["西班牙语", "Hola", "你好吗?"],
];

const tabledata = { 
  headers: ["语言", "正式", "非正式"], 
  rows: rows 
};

(async function () {
  const ini = await initLip();
  const lip = new Lipgloss();

  const table = lip.newTable({
    data: tabledata,
    table: { border: "rounded", color: "99", width: 100 },
    header: { color: "212", bold: true },
    rows: { even: { color: "246" } },
  });

  console.log(table);
})();

进入全屏 退出全屏

我们也可以用十六进制代码来表示颜色(见结尾处的完整示例)

**结果是:**

![表格](https://imgapi.imooc.com/673fe64109e4af6c08000164.jpg)

简单吧?接下来,我们来创建一个列表。

快速的棕色狐狸跳过了懒惰的狗。

## 列出

目前,我们可以显示一个简单的列表。它是这样工作的:
const subtle = { Light: "#D9DCCF", Dark: "#383838" };
const special = { Light: "#43BF6D", Dark: "#73F59F" };

const list = lip.List({
  data: ["葡萄柚", "柚子", "酸橙", "香橙", "金柑"],
  selected: [],
  listStyle: "字母",
  styles: {
    numeratorColor: special.Dark,
    itemColor: subtle.Dark,
    marginRight: 1,
  },
});
const combined = table + "\n\n" + list;
console.log(combined);

全屏 退出全屏

![这是一张图片](https://imgapi.imooc.com/673fe64209a9440308000260.jpg)

**自定义选定项目**  

让我们给选定的项目添加自定义图标(例如,✅),让它看起来更酷。
const customList = lip.List({
  data: ["葡萄柚", "柚子", "酸橙", "香橙", "金柑"],
  selected: ["葡萄柚", "柚子"],
  listStyle: "custom",
  customEnum: "✅",
  styles: {
    numeratorColor: special.Dark,
    itemColor: subtle.Dark,
    marginRight: 1,
  },
});

console.log(customList);

全屏模式 退出全屏

所选项目会显示✅。

![图片描述:插图说明](https://imgapi.imooc.com/673fe643091910a108000275.jpg)  
点击图片可查看大图

——

## Markdown 解析

Charsm 负责使用 Charm 的 **[Glamour](https://github.com/charmbracelet/glamour)** 库来渲染 markdown 内容。
const content = `
# 一个今日菜单

## 开胃菜
| 名称        | 价格 | 备注                           |
| ----------- | ----- | ------------------------------- |
| 腌菜        | $2    | 只是一道开胃菜                 |
| 番茄汤      | $4    | 用圣马扎诺番茄制成             |

## 甜点
| 名称         | 价格 | 备注                 |
| ------------ | ----- | --------------------- |
| 豆沙煎饼     | $4    | 兔子看起来很好吃       |
| 奶油泡芙     | $3    | 非常奶油味!          |

祝您用餐愉快!
`;

console.log(lip.RenderMD(content, "tokyo-night"));

全屏查看 / 退出全屏

* * *

## 自定义风格

可以把样式想象成终端里的 CSS。这里告诉你如何创建你自己的样式:
  lip.createStyle({
    id: "primary",
    canvasColor: { color: "#7D56F4" },
    border: { type: "rounded", sides: [true] },
    // 边距和填充的上下左右
    padding: [6, 8, 6, 8],
    margin: [0, 8, 8, 8],
    bold: true,
    // align: 'center',
    width: 10,
    height: 12,

  });
 lip.createStyle({
    id: "secondary",
    canvasColor: { color: "#7D56F4" },
    border: { type: "rounded", background: "#0056b3", sides: [true, false]},
    padding: [6, 8, 6, 8],
    margin: [0, 0, 8, 1],
    bold: true,
    // 垂直对齐
    alignV: "bottom",
    // 用于定义次要样式,宽度和高度与主样式相同
    width: 10,
    height: 12,

  });

全屏 退出全屏

要将这种样式应用到文本上:

// 这是将值“Hello, charsm!”和id设置为"primary"的应用示例。
const styledText = lip.apply({ value: "Hello, charsm!", id: "primary" });
console.log(styledText);


全屏 退出

查看 [readme](https://github.com/SfundoMhlungu/charsm) 以获取更多选项,或者更好的是,这里有一个 "全面" 的 [示例](https://github.com/SfundoMhlungu/charsm-example)

想要布局?Charsm支持简单的类似flex的布局:
  const a = lip.apply({ value: "Charsmmm", id: "secondary" }) // 定义a变量

  const b = lip.apply({ value: "🔥🦾🍕", id: "primary" }) // 定义b变量
  const c = lip.apply({ value: 'Charsmmm', id: "secondary" }) // 定义c变量

const res = lip.join({
  direction: "horizontal",
  elements: [a, b, c],
  position: "left",
}); // 合并结果

console.log(res); // 输出结果

点击全屏。点击退出全屏。

* * *

## 结尾

就这样吧!使用charsm,你可以展示表格、列表和Markdown,并且甚至还可以自定义样式——甚至可以将列表或Markdown文本包裹在终端内显示,因为它们本质上都是文本格式。
  console.log(lip.apply({value: combined, id: "primary"}))


全屏/退出全屏

表格和列表项将会被一个边框包裹,同时包含内边距和外边距。

![打包好的列表和表格](https://imgapi.imooc.com/673fe645094e80b108000430.jpg)

这只是个开始。我很快会添加互动元素,比如表单,所以请继续关注哦。尽情享受用JavaScript构建你自己的漂亮终端界面的乐趣吧!

你可以在[substack](https://sifundo.substack.com/)找到我写的短文章和个人文章,以及我在[x](https://x.com/codelit09)上的账号。

干了!
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消