泡泡茶中的介绍
#go #codenewbie #100devs #tui

在命令行中做事很酷,可以使您觉得自己像黑客电影中的英雄。但是,它也可以通过单色雪崩的文字感觉到老式的感觉,或者用所有命令线标志和美元标志前缀和不同的方式吓倒了。

但是,命令行不是使用终端的唯一方法,也有 tuis ,终端用户界面,这给您的程序带来了更友好的感觉。我真的很喜欢Tuis,因为他们觉得自己像是新的和旧的。在Go中,最近的Bubble Tea库和all of Charm Bracelet's other tools,由于使制作Tuis变得容易引起了很多关注。

到目前为止,泡泡茶的优势是:

  • 使用与浏览器UI框架共享的Elm architecture,因此,如果您已经完成了一些React,Vue或Elm,它会感到熟悉
  • ELM体系结构不仅是现代前端开发人员熟悉的,而且是组织UI代码的好方法,因此它有利于简单地构建应用程序并以可管理的方式构建其逻辑
  • 因为它正在走,所以语言的一致语法有利于阅读他人的代码
  • 来学习

在本系列中,如果您正在执行#100DEVS或其中一个程序中的程序,我将从头开始构建一个基本的TUI应用程序,以记录您每天在代码中学习的内容#100Daysofcode家族。在我写这篇文章时,尚未完成,因此每个教程都将关注特定概念。大约路线图将是:

  • ð£编写一个简单的Hello World应用程序,并了解其架构的工作原理
  • ð构建我们的第一个真正的泡泡茶组件,菜单
  • - 使用类似于CSS的Lipgloss
  • ,使我们的菜单看起来很酷。
  • ð将路由添加到我们的应用程序显示不同页面
  • ð«§使用其他人使用的泡泡茶组件,使用Bubbles
  • ð将我们的登机手机保存到JSON文件

,请准备好您的终端和Boba大小的稻草,因为没有进一步的ADO是时候跳入泡泡茶了!

ð§编写我们的第一个基本应用

作为第一步,我们将在泡泡茶中制作一个“ Hello World”应用程序,您可以通过按CTRL+C退出,这也将向我们介绍泡泡茶应用的每个部分。

首先,在一个名为“ Code-Journal”的新目录中,运行:

go mod init
go get github.com/charmbracelet/bubbletea

然后,创建一个名为app.go的文件,并添加以下代码:

package main

import (
    tea "github.com/charmbracelet/bubbletea"
)

func main() {
    p := tea.NewProgram(
        newSimplePage("This app is under construction"),
    )
    if err := p.Start(); err != nil {
        panic(err)
    }
}

然后,让我们制作另一个名为simple_page.go的文件,该文件包含我们的第一个UI,一个简单的页面,仅显示一些文本:

package main

import (
    "fmt"
    "strings"

    tea "github.com/charmbracelet/bubbletea"
)

// MODEL DATA

type simplePage struct { text string }

func newSimplePage(text string) simplePage {
    return simplePage{text: text}
}

func (s simplePage) Init() tea.Cmd { return nil }

// VIEW

func (s simplePage) View() string {
    textLen := len(s.text)
    topAndBottomBar := strings.Repeat("*", textLen + 4)
    return fmt.Sprintf(
        "%s\n* %s *\n%s\n\nPress Ctrl+C to exit",
        topAndBottomBar, s.text, topAndBottomBar,
    )
}

// UPDATE

func (s simplePage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg.(type) {
    case tea.KeyMsg:
        switch msg.(tea.KeyMsg).String() {
        case "ctrl+c":
            return s, tea.Quit
        }
    }
    return s, nil
}

在分解代码之前,让我们运行它,看看它的作用。在您的终端中,运行:

go build
./code-journal

您应该看到这样的东西:

Terminal displaying the text "This app is under construction", surrounded by asterisks and the message "Press Ctrl+C to exit" below it

酷!您的第一个泡泡茶应用程序正在运行。现在让我们仔细研究代码。

ð§模型是泡泡茶的主要接口

主函数通过使用simplePage模型创建新程序来启动程序。

func main() {
    p := tea.NewProgram(
        newSimplePage("This app is under construction"),
    )
    if err := p.Start(); err != nil {
        panic(err)
    }
}

我们称为tea.NewProgram,其签名是:

func NewProgram(initialModel Model) *Program

然后调用该程序的启动方法启动我们的应用程序。但是什么是initialModel

Model是泡泡茶的主要接口。它有三种方法:

type Model interface {
    Init() Cmd
    Update(msg Msg) (Model, Cmd)
    View() string
}

应用程序启动时,Init方法是调用的,返回tea.CmdCmd或多或少是“幕后发生的东西”,例如加载数据或流动时间。但是对于当前的教程,我们没有任何背景内容,所以我们的init方法只是返回nil

func (s simplePage) Init() tea.Cmd { return nil }

接下来,我们有了View方法。气泡茶的酷抽象之一是您的整个UI的显示是字符串!,而View是您制作该字符串的地方。

func (s simplePage) View() string {
    textLen := len(s.text)
    topAndBottomBar := strings.Repeat("*", textLen + 4)
    return fmt.Sprintf(
        "%s\n* %s *\n%s\n\nPress Ctrl+C to exit",
        topAndBottomBar, s.text, topAndBottomBar,
    )
}

因此,我们将simplePage的文本放入由星号制成的盒子中,底部有一条消息,说“按Ctrl+C退出”

但是,如果我们无法处理用户输入,我们将无法退出应用程序,因此这就是我们的Update方法的所在地。

func (s simplePage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    switch msg.(type) {
    case tea.KeyMsg:
        switch msg.(tea.KeyMsg).String() {
        case "ctrl+c":
            return s, tea.Quit
        }
    }
    return s, nil
}

Update方法接收tea.Msg并返回一个新的tea.Model,有时是tea.Cmd(例如,如果操作导致检索一些数据或计时器删除)。

a tea.Msg的类型签名是

type Msg interface {}

因此,它可以是任何类型,并且可以携带尽可能多或少的数据。如果您在那里完成了前端,则有点像JavaScript中的浏览器事件;计时器事件不会携带任何数据,单击事件告诉您点击的内容,等等。

我们处理的消息是tea.KeyMsg,它代表键盘输入。我们正在检查用户是否按CTRL+C,如果是这样,我们返回tea.Quit命令,该命令是类型tea.Cmd,并告诉Bubble Tea退出应用程序。

对于任何其他类型的输入,我们什么都不做。我们只是返回模型。但是,如果我们在做类似UI导航之类的事情,那么我们将更改模型上的某些字段,然后返回,从而导致UI更新。这就是我们将在下一个教程中看到的内容,在该教程中,我们将制作菜单组件!