Flutter样式管理插件style_dart的使用
Flutter样式管理插件style_dart的使用
style_dart简介
style_dart 是一个基于Flutter编码风格编写的后端框架。你可以通过这篇文章了解我们的主要动机、目的以及它的一般外观。文档和网站将在不久后开发完成。
加入Discord社区
![]()
开始使用
1)创建一个简单的命令行Dart应用
首先,你需要创建一个简单的Dart命令行应用。
2)添加依赖
在pubspec.yaml文件中添加以下依赖:
dependencies:
style_dart: latest
3)创建一个服务器
类似于Flutter,“一切皆组件”的结构在Style中也被广泛使用。通过调用runService(MyComponent())方法可以运行一个Style应用程序。
定义一个组件
有一个组件用于创建简单的服务器:Server。它是“MaterialApp”或“CupertinoApp”在Flutter中的等价物。
Server是一个ServiceOwner。ServiceOwner持有状态、定时任务和组件树。目前尚未实现,但诸如MicroService和ServiceServer(用于在服务器/微服务之间共享日志记录器等服务)这样的组件也是ServiceOwner。
Server接收并持有主网关(children)、默认服务(如httpService)、根端点(rootEndpoint)、异常端点等。
现在让我们创建一个简单的HTTP服务器:
class MyServer extends StatelessComponent {
const MyServer({Key? key}) : super(key: key);
@override
Component build(BuildContext context) {
return Server(
/// 默认监听localhost:80
httpService: DefaultHttpServiceHandler(
host: "localhost",
port: 8080,
),
children: [
// 主网关
],
);
}
}
启动服务器
void main() {
runService(MyServer());
}
现在,服务器已经准备好从本地主机启动,但我们还需要定义端点。
4)创建一个端点
端点用于处理客户端请求的函数。
“Endpoint”是一个组件,它可以作为组件参数放置。但是,组件树中的所有终点都必须以Endpoint结尾,并且端点不能有子节点。

方框是Component,圆圈是Endpoint。
现在让我们创建一个返回“Hello World!”的端点。
class HelloEndpoint extends Endpoint {
@override
FutureOr<Object> onCall(Request request) {
return "Hello World!";
}
}
5)将端点放在路由上
处理请求的主要Gateway是Server的children值。
在所有Endpoint与它们之上的Gateway之间必须有一个Route。否则,在构建服务器时会报错。
现在让我们将端点放在响应“http://localhost/hello”请求的路由上。
class MyServer extends StatelessComponent {
const MyServer({Key? key}) : super(key: key);
@override
Component build(BuildContext context) {
return Server(
httpService: DefaultHttpServiceHandler(
host: "localhost",
port: 8080,
),
children: [
Route("hello", root: HelloEndpoint())
],
);
}
}
Route接受一个root和一个child。
root处理以输入路径段结尾的请求。
在这个例子中,HelloEndpoint处理请求“http://localhost/hello”。
如果我们要处理“hello/*”及其子路由,必须定义child参数。
如果我们要使用HelloEndpoint处理“hello/*”及其子路由,则需要设置handleUnknownAsRoot为true。
请求
现在通过dart run或IDE的运行命令启动服务器。
5)添加中间件(Gate)
我将创建中间件函数的组件命名为Gate。
Gate的onRequest函数处理请求并等待请求或响应。
如果返回值是Request,请求将继续。这可以用来操纵请求内容。
如果返回值是Response,响应将发送给客户端。
此外,如果你想发送错误消息,此函数中抛出的异常将由上下文的ExceptionWrapper处理。
示例中的Gate仅适用于“host/api/users/*”。
第二个示例中的AuthFilterGate是一个Gate实现,可选地只接受经过身份验证的用户。
由于Style具有模块化结构,它将有许多开发者贡献的现成组件。
以下示例还展示了Gateway和路径段参数(“name”)的用法示例。
class MyServer extends StatelessComponent {
const MyServer({Key? key}) : super(key: key);
@override
Component build(BuildContext context) {
return Server(
children: [
// host/api/
Route(
"api",
child: Gateway(
children: [
/// 中间件在这里 :)
Gate(
onRequest: (request) {
// 进行一些操作
return request; // 返回 Request 或 Response
},
// host/api/users/
child: Route("users",
// host/api/users/{name}
child: Route("{name}",
root: SimpleEndpoint((req, c) {
// 使用此上下文的数据访问处理请求
return Create(
collection: "greeters",
data: {"greeter": req.arguments["name"]},
);
}))),
),
// host/api/posts
Route("posts",
root: AuthFilterGate(
child: SimpleEndpoint.static("Hi"))),
],
),
),
],
);
}
}
第一个Gate示例处理“/api/users”的根段及其所有子段。
在第二个示例中,它仅处理“api/posts”的根段。
6)添加自定义异常消息
你可以自定义处理异常的端点。
可以通过确切类型(例如下面的例子)或超类型(例如ClientError或Exception)进行定制。除非重新包装,否则适用于所有子组件。
确定处理异常的端点时,检查顺序为:确切类型 -> (如果是实现)超类型(例如ClientError) -> Exception。

class MyStyleExEndpoint extends ExceptionEndpoint<BadRequest> {
MyStyleExEndpoint() : super();
@override
FutureOr<Object> onError(Message message, BadRequest exception, StackTrace stackTrace) {
return "Will always be bad !!!";
}
}
// 在你的组件树中添加该组件。
Component getExceptionWrapper() {
return ExceptionWrapper<BadRequest>(
child: Route("always_throw", root: Throw(BadRequest())),
exceptionEndpoint: MyExceptionEndpoint());
}
Throw是一个始终发送异常的端点。
7)添加你的数据访问
对于后端应用,访问数据是必需的。
在Style中,有一些我称之为基本服务的结构。
当前可用的服务包括:DataAccess、HttpService、Logger、Authorization、Crypto和WebSocketService。
每个服务都有其特定的功能。
定义服务
所有服务都可以作为Server的默认服务分配。
class MyServer extends StatelessComponent {
const MyServer({Key? key}) : super(key: key);
@override
Component build(BuildContext context) {
return Server(
httpService: DefaultHttpServiceHandler(),
webSocketService: StyleTicketBaseWebSocketService(),
logger: MyLogger(),
dataAccess: DataAccess(MongoDbDataAccessImplementation()),
children: [
Route("hello", root: HelloEndpoint())
]);
}
}
MongoDB实现可通过style_mongo包获得。
服务包装器
你可以为组件树的一部分使用不同的服务。只要不重新包装,这些包装就是有效的。
class MyServer extends StatelessComponent {
const MyServer({Key? key}) : super(key: key);
@override
Component build(BuildContext context) {
return Server(
// 服务器默认
dataAccess: DataAccess(MongoDbDataAccessImplementation()),
children: [
Route("hello", root: HelloEndpoint()),
// 为“/other/*”使用不同的服务
ServiceWrapper<DataAccess>(
child: Route("other", root: HelloEndpoint()),
service: DataAccess(SimpleCacheDataAccess()),
),
],
);
}
}
使用服务
你可以通过这种方式访问所有服务:
DataAccess.of(context)
8)访问数据
有许多方式可以访问你的数据。一种是在端点的onCall函数中返回一个Event。
你也可以直接访问函数:DataAccess.of(context).read(...)。
以下端点被放置在“/greet/{name}”路由上。
创建问候者
class HelloEndpoint extends Endpoint {
@override
FutureOr<Object> onCall(Request request) {
return Create(
collection: "greeters",
data: {"greeter": request.arguments["name"]},
);
}
}
读取所有问候者
class GreetersEndpoint extends Endpoint {
@override
FutureOr<Object> onCall(Request request) {
return ReadMultiple(collection: "greeters");
}
}
自动化访问
你可以通过单一端点处理所有数据操作。
你可以完全自己处理,也可以使用现成的组件。
AccessPoint
AccessPoint接受一个回调函数,该函数运行并返回。这个AccessEvent由上下文的DataAccess处理。
class MyServer extends StatelessComponent {
const MyServer({Key? key}) : super(key: key);
@override
Component build(BuildContext context) {
return Server(
httpService: DefaultHttpServiceHandler(),
children: [
Route("col",
// AccessEvent
root: AccessPoint((req, ctx) {
return AccessEvent(
access: Access(
type: _getAccessType(req),
collection: req.arguments["col"],
// 可选参数
// query
// identifier
// data
// pipeline
// settings
),
request: req);
})),
],
);
}
}
RestApi
根据REST API标准工作的现成访问点,既可以在核心包中使用,也可以由开发者开发。
RestAccessPoint("route")
更多关于Flutter样式管理插件style_dart的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter样式管理插件style_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
style_dart 是一个用于 Flutter 的样式管理插件,它允许开发者将样式集中管理,从而提高代码的可维护性和可读性。通过 style_dart,你可以将颜色、字体、边距等样式定义在一个地方,并在整个应用中重复使用。
安装 style_dart
首先,你需要在 pubspec.yaml 文件中添加 style_dart 依赖:
dependencies:
flutter:
sdk: flutter
style_dart: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get 来安装依赖。
基本用法
-
创建样式文件
创建一个 Dart 文件(例如
app_styles.dart)来定义你的样式。import 'package:style_dart/style_dart.dart'; final appStyles = StyleSheet({ 'colors': { 'primary': Colors.blue, 'secondary': Colors.green, 'background': Colors.white, }, 'textStyles': { 'heading': TextStyle(fontSize: 24, fontWeight: FontWeight.bold), 'body': TextStyle(fontSize: 16, color: Colors.black), }, 'spacing': { 'small': 8.0, 'medium': 16.0, 'large': 24.0, }, }); -
在应用中使用样式
在 Flutter 应用中,你可以通过
StyleProvider来提供样式,并在需要的地方使用它们。import 'package:flutter/material.dart'; import 'app_styles.dart'; // 导入样式文件 void main() { runApp( StyleProvider( styleSheet: appStyles, child: MyApp(), ), ); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { final style = Style.of(context); return Scaffold( backgroundColor: style.colors['background'], appBar: AppBar( title: Text('Style Dart Example'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'Heading', style: style.textStyles['heading'], ), SizedBox(height: style.spacing['medium']), Text( 'Body Text', style: style.textStyles['body'], ), ], ), ), ); } }
样式嵌套和覆盖
style_dart 允许你嵌套样式表,并且可以在需要时覆盖父样式。
final nestedStyles = StyleSheet({
'colors': {
'primary': Colors.red,
},
}, parent: appStyles);
在使用 nestedStyles 时,primary 颜色将被覆盖为红色,而其他样式(如 secondary、background 等)将继承自 appStyles。
动态样式
你还可以根据应用程序的状态动态生成样式。
final dynamicStyles = StyleSheet({
'colors': {
'primary': (context) => Theme.of(context).primaryColor,
},
});

