Riverpod 是 Flutter 的一种状态管理框架,由 Provider 的作者重新设计,
目标是:更安全、更灵活、更强大。
相比传统 provider:
在 pubspec.yaml 中添加依赖:
dependencies:
flutter_riverpod: ^2.5.1
然后在根组件包裹 ProviderScope:
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/material.dart';
void main() {
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
适用于常量或计算值。
final nameProvider = Provider((ref) => 'Lin Jianyou');
class MyWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final name = ref.watch(nameProvider);
return Text('Hello, $name');
}
}
适用于简单的局部状态(例如计数器)。
final counterProvider = StateProvider<int>((ref) => 0);
class CounterWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: const Text('Increment'),
),
],
);
}
}
适用于有业务逻辑的状态,比如 Todo、登录状态等。
// 状态类
class Counter extends StateNotifier<int> {
Counter() : super(0);
void increment() => state++;
void reset() => state = 0;
}
// Provider
final counterNotifierProvider = StateNotifierProvider<Counter, int>((ref) {
return Counter();
});
// 使用
class CounterWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterNotifierProvider);
final counter = ref.read(counterNotifierProvider.notifier);
return Column(
children: [
Text('Count: $count'),
ElevatedButton(
onPressed: counter.increment,
child: const Text('Add'),
),
],
);
}
}
适用于 异步数据获取(网络请求、数据库等)。
final userProvider = FutureProvider<String>((ref) async {
await Future.delayed(const Duration(seconds: 1));
return 'User: Lin';
});
class UserWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userProvider);
return userAsync.when(
data: (data) => Text(data),
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
);
}
}
适用于如 WebSocket、数据库订阅等持续变化的数据。
final timeProvider = StreamProvider<int>((ref) async* {
for (var i = 0; i < 10; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i;
}
});
class TimeWidget extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final time = ref.watch(timeProvider);
return time.when(
data: (value) => Text('Time: $value'),
loading: () => const CircularProgressIndicator(),
error: (e, _) => Text('Error: $e'),
);
}
}
你可以让一个 provider 依赖另一个 provider:
final priceProvider = Provider((ref) => 100);
final taxProvider = Provider((ref) => 0.1);
final totalPriceProvider = Provider((ref) {
final price = ref.watch(priceProvider);
final tax = ref.watch(taxProvider);
return price * (1 + tax);
});
ref.listen 用于在值变化时执行副作用(比如跳转、弹窗等)。
ref.listen<int>(counterProvider, (previous, next) {
if (next > 10) {
print('超过10了!');
}
});
文件结构建议:
lib/
├─ main.dart
├─ providers/
│ ├─ user_provider.dart
│ ├─ counter_provider.dart
├─ models/
│ ├─ user.dart
├─ screens/
│ ├─ home_screen.dart
│ ├─ profile_screen.dart
可视化调试: 安装 Riverpod Devtools
dart pub global activate riverpod_cli
riverpod watch
在 Flutter DevTools 中能看到 provider 状态变化。
| 场景 | 推荐 Provider 类型 |
|---|---|
| 简单计数 | StateProvider |
| 网络请求 | FutureProvider |
| 长连接流 | StreamProvider |
| 复杂业务逻辑 | StateNotifierProvider |
| 常量/配置 | Provider |
官方示例架构推荐(Clean + State Management)
Flutter 团队在官方 sample 中(如 Flutter Architecture Samples)推荐:
lib/
├─ data/ ← Repository 层
├─ models/ ← 业务数据模型
├─ providers/ ← 状态定义(用 Provider / Riverpod)
├─ screens/ ← UI 层
└─ main.dart
并使用:
UI 负责显示 (ConsumerWidget)
Provider/Riverpod 负责状态与逻辑
Repository 负责网络或数据库
单引号容易被翻译成转义编码字符,对于md和mdx的导入和链接会产生影响。
[]()格式的超链接容易被翻译出现格式错误
还有就是有些超链接的地址出现问题。
如:
<details>
<summary>标题</summary>
</details>
标签会被翻译成中文简体或繁体
在多国语言翻译时,原来的资源图片等引用路径发生了变化。
如果引用更目录的可以使用@site/路径方式替换
在md或mdx里翻译软件容易翻译掉import语法
如果你想私有部署 pip 包,也就是说,不发布到 PyPI,而是自己内部使用,有几种方式可以实现。下面是常见的做法和适合的场景:
打包你的包:
python -m build
然后安装:
pip install dist/your_package_name-0.1.0-py3-none-any.whl
也可以不打包,直接安装源码目录:
pip install .
或:
pip install -e . # 开发模式(修改源码立即生效)
推荐优惠网站:https://lowendbox.com/best-cheap-vps-hosting-updated-2020/ 不定期会有超低优惠价格的虚拟主机售卖。低到单核4G内存的主机只要每年10美元左右,平均每个月7元RMB左右。
根据自己的需要,选择无限流量还是有限的带宽流量。当然如果经济允许可以稍微购买些性能更好的主机。比如双核vCPU或4核vCPU的套餐。鄙人买的是单核每年10美元左右的套餐:https://vpshostingservice.co/ 。优惠套餐不是每次都一样,可以时刻关注有最新优惠促销活动。
一般都是买linux平台的vps主机,服务器基本都是linux平台的无界面主机,只需要终端控制台即可方便安装各种软件。
Github pages默认支持Jekyll静态网页生成器,也就是说你的github上的某个仓库如果包含了docs或public网页内容或markdown文件内容,会以Jekyll方式编译网站自动托管到Github pages上。域名将会是 username.gihub.io/repo/,username替换成你的github账号名,repo替换成你的仓库名。
如果仓库名为username.gihub.io,这也正式你的github pages的首页域名,也是创建github pages必需创建的公开仓库!