Skip to main content
Version: Next 🚧

标记

标记(Markup)是指使用标记语言编写的文本,用于描述文档的结构和格式。它通过在文本中插入特定的标记(标签)来指示文档中的元素类型和其它相关信息。

借助 lcui-cli,你有多种编写界面的方式:使用 XML 这种标记语言,或是用 YAML 和 JSON 格式的文件,又或是在 JavaScript 或 TypeScript 代码中使用 JSX 语法。

TypeScript

项目中的界面部分是使用 TypeScript 语言描述的,源文件是 .tsx 后缀,它们经过 lcui-cli 工具编译后会生成同名的 .tsx.h 后缀文件。

不用担心,你无需学习 TypeScript 语言,代码中只用到 TypeScript 的基本的语法, 大多数情况下你只需要参考以下代码片段来编写即可:

// 引入 LCUI 的预置组件
import React, { Text, TextInput, Button } from "@lcui/react";
// 从图标库中引入图标
import { EmojiSparkle } from "@lcui/react-icons";
// 引入图标库的样式文件
import "@lcui/react-icons/dist/style.css";
// 引入其它组件
import About from "../components/about";

export default function Home() {
return (
<div className="container">
<EmojiSparkle />
<About />
<div className="input-group">
<Text>Enter a message and save it.</Text>
<TextInput $ref="input_message" placeholder="eg: hello, world!" />
<Button $ref="btn_save_message">Save</Button>
</div>
</div>
);
}

import 语句用于导入由另一个模块导出的绑定

@lcui/react 是一个用于 LCUI 应用程序开发的 React 库,提供 TypeScript 类型声明、React 版预置组件(例如:Text,TextInput,Button),配合 @lcui/cli 使用。与 React 库的不同之处在于,它仅允许使用 JSX 的基本特性,不提供 useState()useEffect() 等函数。这意味着你只能将 JSX 当成静态的 XML 或 HTML 这类标记语言来写。

@lcui/react-icons 是专为 LCUI 适配的图标库,图标都来自 Fluent UI 系统图标

export default 语句用于导出默认绑定,后面接的是 function Home,也就是默认导出 Home 函数。

function Home() { ... } 是函数声明,其中函数名称 Home 将会作为 C 代码中注册组件时使用的名称。

函数内部返回的是 JSX 表达式。JSX 与 HTML 写法相似,但比它更严格。你必须关闭标签,如 <br/>。你的组件也不能返回多个 JSX 标记。你必须将它们封装到一个共享的父级中,如 <div></div>

JSX 元素的 $ref 属性用于创建引用,编译后会在 refs 结构体中创建同名成员,我们可以通过它直接访问 ui_widget_t 组件实例。

lcui-cli 对 tsx 文件的编译过程是先将 tsx 文件及其依赖的所有模块编译为 js 文件并输出到 .lcui 目录中,之后执行模块中导出的组件函数,将返回结果转译成 C 代码,最终输出为同名的 .h 后缀的文件。

XML

LCUI 支持从 XML 文件中加载界面。XML 文件内容写法如下:

<?xml version="1.0" encoding="UTF-8" ?>
<lcui-app>
<resource type="text/css" src="home.css"/>
<resource type="application/font-ttf" src="iconfont.ttf"/>
<ui>
<text>Enter a message and save it.</text>
<textedit ref="input-message" placeholder="eg: hello, world!" />
<button ref="btn-save-message">Save</button>
<text ref="feedback" class="feedback">Message has been saved!</text>
</ui>
</lcui-app>

你可以使用 ui_xml.h 头文件提供的 ui_load_xml_file() 函数加载 XML 文件。

#include <ui_xml.h>

...

ui_widget_t *wrapper = ui_load_xml_file("path/to/file.xml");

需要注意的是,这一功能可能会在未来的版本中移除,因为 lcui-cli 能够将 XML 转译成直接构建界面的 C 代码,这比在运行时调用 libxml2 库的接口解析 XML 文档再构建界面的性能更高。

JSON

lcui-cli 编译 XML、YAML、TSX 的中间结果是 JSON 格式的数据,最终都是由 JSON 编译器将结果转换成 C 代码的。

JSON 写法如下:

{
"name": "lcui-app",
"children": [
{
"name": "resource",
"attributes": { "type": "text/css", "src": "home.css" }
},
{
"name": "resource",
"attributes": {
"type": "application/font-ttf",
"src": "iconfont.ttf"
}
},
{
"name": "ui",
"children": [
{
"name": "text",
"children": [
{ "type": "text", "text": "Enter a message and save it." }
]
},
{
"name": "textinput",
"attributes": {
"ref": "input-message",
"placeholder": "eg: hello, world!"
}
},
{
"name": "button",
"attributes": { "ref": "btn-save-message" },
"children": [{ "type": "text", "text": "Save" }]
},
{
"name": "text",
"attributes": { "ref": "feedback", "class": "feedback" },
"children": [{ "type": "text", "text": "Message has been saved!" }]
}
]
}
]
}

YAML

YAML 的写法比 JSON 更精简:

name: lcui-app
children:
- name: resource
attributes:
type: text/css
src: home.css
- name: resource
attributes:
type: application/font-ttf
src: iconfont.ttf
- name: ui
children:
- name: text
children:
- type: text
text: Enter a message and save it.
- name: textinput
attributes:
ref: input-message
placeholder: "eg: hello, world!"
- name: button
attributes:
ref: btn-save-message
children:
- type: text
text: Save
- name: text
attributes:
ref: feedback
class: feedback
children:
- type: text
text: Message has been saved!