dart_web
Dart 的实验性 Web 框架。支持 SPA 和 SSR。
依赖于 package:domino 及其增量 DOM 渲染方法进行动态更新。
功能
- 服务器端渲染
- 类似于 Flutter 的组件模型
- 客户端组件数据的自动水合
开始使用
要开始,请使用 web-simple 模板和 dart create 工具创建一个新的 Dart Web 应用。
dart create -t web-simple my_web_app
cd my_web_app
接下来,您需要激活 webdev,它负责 Web 应用的一般服务和构建,并将 dart_web 添加为依赖项。
dart pub global activate webdev
dart pub add dart_web --git-url=https://github.com/schultek/dart_web
现在是时候创建您的主组件了,它将是您应用的起点。将以下代码放在 lib/components/app.dart 中
import 'package:dart_web/dart_web.dart';
class App extends StatelessComponent {
@override
Iterable<Component> build(BuildContext context) sync* {
yield DomComponent(
tag: 'p',
child: Text('Hello World'),
);
}
}
这将稍后渲染一个带有“Hello World”内容的单个段落元素。
现在您需要通过将它传递给 dart_web 提供的 runApp 方法来使用此组件。
由于我们实际上在构建两个应用——一个在浏览器中,一个在服务器上——我们需要为它们设置单独的入口点。
- 对于浏览器应用,
web/文件夹中已经有一个main.dart。将其内容更改为以下内容:
import 'package:dart_web/dart_web.dart';
import 'package:my_web_app/components/app.dart';
void main() {
runApp(App(), id: 'output');
}
这将导入 App 组件并将其与根元素的 ID 一起传递给 runApp。
请注意,这是 index.html 文件中生成的 <div id="output"></div> 的 ID。您可以根据需要更改 ID,但它必须在两个文件中匹配。
- 对于服务器应用,在
lib/文件夹中创建一个新的main.dart文件并插入以下内容:
import 'package:dart_web/dart_web.dart';
import 'components/app.dart';
void main() {
runApp(App(), id: 'output');
}
您会发现两者对于这两个入口点来说基本相同,这正是设计使然。
但是,您仍然希望将它们分开,以便以后可以添加平台特定代码。
最后,使用以下命令运行开发服务器:
dart run dart_web serve
这将启动一个服务器,地址为 localhost:8080。您现在可以开始开发您的 Web 应用了。
另外,请注意,当您在代码中更改某些内容(例如“Hello World”文本)时,浏览器会自动刷新页面。
组件
dart_web 在构建应用程序时使用了类似于 Flutter 的结构。
您可以通过覆盖 build() 方法来定义自定义的无状态或有状态组件(非小部件)。
由于 HTML 渲染的工作方式与 Flutter 的绘制方法不同,因此这里是组件模型的核心方面和区别:
-
build()方法返回一个Iterable<Component>而不是单个组件。这是因为 HTML 节点可以有多个子节点。
推荐使用 **同步生成器**。只需在方法定义中使用sync*关键字,然后yield一个或多个组件。 -
您只能使用两个现有组件:
DomComponent和Text。
DomComponent渲染带有指定标签的 HTML 元素。您还可以设置 ID、属性和事件。它还接受子组件。Text渲染一些原始 HTML 文本。它只接收一个字符串,没有其他内容。*像平常在 HTML 和 CSS 中一样,通过父元素来设置样式*。
StatefulComponent的State支持在服务器上预加载一些数据。要使用此功能,请覆盖FutureOr<T?> preloadData()方法。请参阅 预加载数据。
预加载数据
在使用服务器端渲染时,您可以在渲染 HTML 之前预加载组件数据。
在客户端初始化应用时,我们也需要访问这些数据以保持渲染的一致性。
使用 dart_web,这已内置在包中,易于实现。
首先,在为 StatefulComponent 定义 State 类时,它会接受一个额外的类型参数,指向您想要加载的数据类型:class MyState extends State<MyStatefulWidget, T>。
请注意,此类型必须是可 JSON 序列化的。
要加载您的数据,请覆盖 FutureOr<T?> preloadData() 方法。这只会在服务器上执行,并且可以返回一个 Future。
现在,在覆盖 initState(T? data) 时,您会收到一个额外的参数,其中包含加载的数据,无论是在服务器上还是在客户端上。
构建
您可以使用以下命令构建您的应用程序:
dart run dart_web build
这将在 build 目录中构建应用程序。
您可以使用 --target 选项选择构建独立的可执行文件,还是构建 AOT 或 JIT 快照。
要运行您构建的应用程序,请执行:
cd build
./app