当前位置: 首页> 游戏> 评测 > 注册深圳公司流程_外贸网站建站多少钱_销售网站排名_电商平台怎么推广

注册深圳公司流程_外贸网站建站多少钱_销售网站排名_电商平台怎么推广

时间:2025/7/9 3:11:02来源:https://blog.csdn.net/liao277218962/article/details/148918637 浏览次数:0次
注册深圳公司流程_外贸网站建站多少钱_销售网站排名_电商平台怎么推广
📚 Flutter 状态管理系列文章目录
  1. Flutter 状态管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux)

  2. setState() 使用详解:原理及注意事项

  3. InheritedWidget 组件使用及原理

  4. Flutter 中 Provider 的使用、注意事项与原理解析(含代码实战)

  5. GetX 用法详细解析以及注意事项

  6. Flutter BLoC 使用详细解析

  7. Flutter MobX 响应式原理与实战详解

  8. Flutter Riverpod 使用详细解析

  9. Riverpod原理解析(实现一个自己的Riverpod

源码地址

📌 Riverpod 是 Flutter 官方推荐的状态管理方案之一,相比 Provider 更灵活、安全、支持组合、异步、热重载、IDE 类型推导。


📁 1. 安装依赖

pubspec.yaml 添加:

dependencies:flutter_riverpod: ^2.5.1

然后执行:

flutter pub get

🧠 2. 核心概念简述

类型描述示例用途
Provider只读数据常量、服务类
StateProvider原始值的可变状态(int/bool)计数器、开关
StateNotifierProvider复杂对象状态 + 控制逻辑列表、对象、业务逻辑
ChangeNotifierProviderChangeNotifier 封装的旧模式第三方 SDK 封装
FutureProvider异步加载网络请求、初始化数据
StreamProvider实时数据流WebSocket、定时器

🧪 3. 实战代码讲解

示例场景:Todo 应用


Provider:静态或只读依赖

final greetingProvider = Provider<String>((ref) {return "Hello, Riverpod!";
});class GreetingWidget extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final greeting = ref.watch(greetingProvider);return Text(greeting);}
}

💡 用于配置、单例、不可变依赖。


StateProvider:简单状态(如 int、bool)

final counterProvider = StateProvider<int>((ref) => 0);class CounterPage extends ConsumerWidget {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: Text('Increment'),),],);}
}

💡 简单值状态管理的首选。


StateNotifierProvider:结构化业务逻辑

定义模型:

class Todo {final String id;final String title;Todo({required this.id, required this.title});
}

定义状态控制器:

class TodoNotifier extends StateNotifier<List<Todo>> {TodoNotifier() : super([]);void add(String title) {final todo = Todo(id: DateTime.now().toIso8601String(), title: title);state = [...state, todo];}void remove(String id) {state = state.where((t) => t.id != id).toList();}
}final todoListProvider =StateNotifierProvider<TodoNotifier, List<Todo>>((ref) => TodoNotifier());

页面使用:

class TodoListView extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final todos = ref.watch(todoListProvider);return ListView(children: todos.map((t) => ListTile(title: Text(t.title),trailing: IconButton(icon: Icon(Icons.delete),onPressed: () => ref.read(todoListProvider.notifier).remove(t.id),),)).toList(),);}
}

💡 面向对象式的推荐写法,利于维护与测试。


ChangeNotifierProvider:传统类兼容封装

class AuthModel extends ChangeNotifier {String _email = '';String get email => _email;void login(String email) {_email = email;notifyListeners();}
}final authProvider = ChangeNotifierProvider((ref) => AuthModel());

使用:

class AuthView extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final auth = ref.watch(authProvider);return Column(children: [Text('Email: ${auth.email}'),ElevatedButton(onPressed: () => ref.read(authProvider).login('user@example.com'),child: Text('Login'),),],);}
}

⚠️ 尽量用于兼容旧代码或外部库。


FutureProvider:异步加载数据

final userInfoProvider = FutureProvider<String>((ref) async {await Future.delayed(Duration(seconds: 1));return "Async User Loaded";
});

使用:

class UserInfoWidget extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final userInfo = ref.watch(userInfoProvider);return userInfo.when(data: (name) => Text('User: $name'),loading: () => CircularProgressIndicator(),error: (e, _) => Text('Error: $e'),);}
}

💡 支持 loading/error/data 三种状态,十分方便。


StreamProvider:实时流监听

final tickProvider = StreamProvider<int>((ref) async* {int count = 0;while (true) {await Future.delayed(Duration(seconds: 1));yield ++count;}
});

使用:

class TimerWidget extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final tick = ref.watch(tickProvider);return tick.when(data: (val) => Text('Tick: $val'),loading: () => Text('Waiting...'),error: (e, _) => Text('Error: $e'),);}
}

💡 非常适合实现 WebSocket、倒计时、后台上传监听等。



🧬 4 Riverpod Provider 的生命周期详解

Riverpod 的每个 Provider 都有清晰的生命周期管理机制,这是它相比 Provider(老版)或 setState 更加安全、强大的关键优势之一。

生命周期由 Riverpod 自动管理,确保资源释放、缓存优化、避免内存泄漏。


🎯 生命周期触发时机概览
生命周期阶段描述对应钩子函数 / 方法
创建第一次被 ref.watch() / ref.read() 使用provider 的构造函数
监听中有 widget 或 provider 依赖它ref.watch() 触发监听
取消监听最后一个监听者移除后,开始进入 dispose 倒计时keepAlive 决定回收策略
销毁无依赖 + 被标记为回收onDispose 触发

📌 1. Provider 的创建与首次使用
  • 只有在首次使用(如 ref.watch())时才真正创建。
  • Provider 是懒加载的(Lazy Initialized)。
final timestampProvider = Provider<DateTime>((ref) {print('✅ 创建时间: ${DateTime.now()}');return DateTime.now();
});

📌 2. 自动销毁与缓存策略
🔁 默认行为:自动销毁(AutoDispose)
  • 若无任何 ref.watch() 使用该 Provider,它会被自动销毁。
  • 优化内存和性能,避免长时间驻留。
final myProvider = Provider.autoDispose<int>((ref) {print('🌀 创建');ref.onDispose(() => print('❌ 销毁'));return 42;
});

使用中断后会触发销毁:

// 页面离开,或 ref.invalidate()

📌 3. 保持活跃 ref.keepAlive()
final counterProvider = Provider.autoDispose<int>((ref) {final link = ref.keepAlive(); // 👈 阻止销毁Future.delayed(Duration(seconds: 30), () {print('🚨 30 秒后允许销毁');link.close(); // 👈 恢复可销毁});ref.onDispose(() {print('⛔ 被销毁');});return 123;
});

✅ 用于防止高频初始化,如网络缓存、状态记录。


📌 4. ref.onDispose()

所有 Provider 都可使用:

ref.onDispose(() {print('🧹 清理资源...');
});

常用于:

  • 关闭连接(如 WebSocket、Stream、Timer)
  • 释放资源(如 Controller、Database)
  • 终止订阅

✅ 总结:各 Provider 生命周期对比
Provider 类型是否可自动销毁是否可 keepAlive是否有 onDispose
Provider❌ 否(持久)✅ 支持✅ 支持
Provider.autoDispose✅ 是✅ 支持✅ 支持
StateProvider❌ 否✅ 支持✅ 支持
StateNotifierProvider❌ 否(除非手动)✅ 支持✅ 支持
FutureProvider.autoDispose✅ 默认✅ 支持✅ 支持
StreamProvider.autoDispose✅ 默认✅ 支持✅ 支持

🛠 应用实战建议
场景建议 Provider 类型
临时页面数据(如表单页).autoDispose 类型
全局共享状态(如登录信息)普通 Provider / StateNotifierProvider
长连接、Timer、Streamref.onDispose + .keepAlive()
一次性请求缓存(配置、Token)使用 keepAlive() 手动控制回收

✅ 5. 多 Provider 合并管理

final appProviders = ProviderContainer(overrides: []);

或使用 ConsumerStatefulWidget 在生命周期中集中监听多个状态。


🧱 6. Riverpod 与传统Provider 的关系

✅ 简明回答:

Riverpod 并不是基于传统 Provider 的封装,它是 完全重写的一个全新状态管理框架,由同一个作者 Remi Rousselet 开发,但底层逻辑、API 设计、运行机制都不同。


🔍 深度解析:Riverpod 与 Provider 的关系
项目ProviderRiverpod
作者Remi RousseletRemi Rousselet
上线时间20182020
设计理念面向 widget tree 的 InheritedWidget独立于 widget tree,可纯 Dart 运行
架构关系Flutter Widget 的封装重新设计的响应式依赖系统(非封装)
生命周期依赖 Widget 生命周期由容器独立管理,更安全可控
热重载支持完整支持热重载(尤其适合大型项目)
Test 测试需依赖 Widget 或 MockContext完全脱离 UI,可单测 provider

🧠 核心区别举例
✅ Provider 示例
ChangeNotifierProvider(create: (_) => CounterModel(),child: MyApp(),
);
  • 必须包在 widget tree 里,依赖 BuildContext
  • 很多依赖关系写在 UI 组件中,不利于拆分测试。

✅ Riverpod 示例
final counterProvider = StateProvider((ref) => 0);
  • 不依赖 WidgetTree,任何地方都可以 ref.watch
  • 甚至可以在纯 Dart 类、后台逻辑中使用,适合模块化架构。

📦 为什么作者重写 Riverpod?

作者自己在 Riverpod 官网解释了:

“Provider 的设计绑定在 widget tree 上,不足以应对复杂、灵活的状态管理需求;Riverpod 是为了解决 Provider 的根本限制而设计的。”

来源:https://riverpod.dev


✅ 总结对比(类比说明)
类比对象ProviderRiverpod
类比 Flutter 状态setState()Bloc / Redux / MobX
类比 HTML 框架jQueryReact + Hooks
是否独立可测❌ 需要 widget tree✅ 完全支持纯 Dart 单测
是否推荐未来使用🟡 小项目可继续用✅ 官方推荐未来项目默认使用 Riverpod

7. 🔄 Provider 到 Riverpod 迁移指南

✅ 1. 概念映射表
Provider 中的概念Riverpod 对应概念用途
ChangeNotifierProviderChangeNotifierProvider(兼容)保持一致,用于 SDK 封装
Provider<T>Provider<T>只读依赖
StateProvider<T>(无)✅ Riverpod 独有,推荐替代 setState管理基本类型如 int、bool
ConsumerWidgetConsumerWidget响应式 UI
context.read()ref.read()读取值,不触发 rebuild
context.watch()ref.watch()读取并监听
MultiProvider❌ 不需要,Riverpod 使用全局注册 Provider提升模块化与性能
依赖于 BuildContext✅ 不依赖 BuildContext更适合逻辑复用、单元测试

⚠️ 2. Provider 示例 VS Riverpod 对比代码
旧:使用 Provider(ChangeNotifier)
class CounterModel extends ChangeNotifier {int _count = 0;int get count => _count;void increment() {_count++;notifyListeners();}
}// 注册
ChangeNotifierProvider(create: (_) => CounterModel())// 使用
final counter = Provider.of<CounterModel>(context);

新:使用 Riverpod(StateNotifier)
final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) {return CounterNotifier();
});class CounterNotifier extends StateNotifier<int> {CounterNotifier() : super(0);void increment() => state++;
}// UI 使用
class CounterWidget extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final count = ref.watch(counterProvider);return Text('$count');}
}

🔁 3. 推荐迁移步骤
步骤内容
✅ 第一步安装 flutter_riverpod 并用 ProviderScope 包裹 MaterialApp
✅ 第二步从功能简单的模块开始迁移(如计数器页面)
✅ 第三步ChangeNotifier 转为 StateNotifier / Notifier
✅ 第四步context.read/watch 替换为 ref.read/watch
✅ 第五步清除旧 Provider 引入,完全替换后删除 Provider

🤝 4. Riverpod 和 Provider 可以共存吗?

可以! 它们不会互相干扰,可用于渐进式迁移。

void main() {runApp(MultiProvider(providers: [ChangeNotifierProvider(create: (_) => OldProvider())],child: ProviderScope(child: MyApp(),),),);
}

📌 注意顺序,ProviderScope 是 Riverpod 的入口容器,MultiProvider 是旧 Provider 的入口。


🧪 5. 测试更简单

Riverpod 的 Provider 不依赖 Widget Tree,可直接测试:

void main() {test('Counter increments', () {final container = ProviderContainer();final notifier = container.read(counterProvider.notifier);notifier.increment();expect(container.read(counterProvider), 1);});
}

🧭 6. 补充推荐迁移写法
✅ 将 Provider 包装类抽离为方法:
Widget build(BuildContext context, WidgetRef ref) {final count = ref.watch(counterProvider);return _buildCountText(count);
}Widget _buildCountText(int count) => Text('$count');

✅ 避免业务逻辑写在 build 方法中,便于测试和维护。


📚 工具推荐
工具用途
riverpod_lintRiverpod 专用 Lint
riverpod_generator自动生成 Notifier 等模板
state_notifier搭配使用,可手动控制状态
freezed状态模型不可变 + 模式匹配

✅ 小结:迁移推荐策略
  • 🧱 小项目:直接重构成 Riverpod(更清晰)
  • 🧬 中大型项目:新模块优先使用 Riverpod,旧模块稳定后再迁移
  • 🧪 单元测试驱动:逻辑类迁移优先(先把模型和 service 拆出来)
  • 🔁 可并存:逐步过渡,保持主 app 稳定

下面是一个完整的 计数器 Counter 示例,包括:

  • ✅ Provider 旧写法(使用 ChangeNotifier
  • ✅ Riverpod 新写法(使用 StateNotifier

每一套代码都包含完整的 main.dartmodelUI,你可以直接运行进行对比。


✅ 迁移前(使用 Provider)
📄 pubspec.yaml 添加依赖
dependencies:flutter:sdk: flutterprovider: ^6.1.0

📁 counter_model.dart
import 'package:flutter/foundation.dart';class CounterModel extends ChangeNotifier {int _count = 0;int get count => _count;void increment() {_count++;notifyListeners();}
}

📄 main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'counter_model.dart';void main() {runApp(ChangeNotifierProvider(create: (_) => CounterModel(),child: MyApp(),),);
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(home: CounterPage(),);}
}class CounterPage extends StatelessWidget {Widget build(BuildContext context) {final counter = Provider.of<CounterModel>(context);return Scaffold(appBar: AppBar(title: Text('Provider Counter')),body: Center(child: Text('Count: ${counter.count}', style: TextStyle(fontSize: 24))),floatingActionButton: FloatingActionButton(onPressed: counter.increment,child: Icon(Icons.add),),);}
}

✅ 迁移后(使用 Riverpod)
📄 pubspec.yaml 添加依赖
dependencies:flutter:sdk: flutterflutter_riverpod: ^2.5.1

📁 counter_notifier.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';// Provider 和逻辑
class CounterNotifier extends StateNotifier<int> {CounterNotifier() : super(0);void increment() => state++;void reset() => state = 0;
}final counterProvider = StateNotifierProvider<CounterNotifier, int>((ref) => CounterNotifier(),
);// 🚀 抽离逻辑方法(对外暴露 API)
int useCounter(WidgetRef ref) => ref.watch(counterProvider);void incrementCounter(WidgetRef ref) => ref.read(counterProvider.notifier).increment();void resetCounter(WidgetRef ref) => ref.read(counterProvider.notifier).reset();

📄 main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'counter_controller.dart';void main() {runApp(const ProviderScope(child: MyApp()));
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: CounterPage());}
}class CounterPage extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final count = useCounter(ref); // 👈 抽离的读取方法return Scaffold(appBar: AppBar(title: Text('抽离逻辑示例')),body: Center(child: Text('Count: $count', style: TextStyle(fontSize: 24))),floatingActionButton: Row(mainAxisAlignment: MainAxisAlignment.end,children: [FloatingActionButton.small(heroTag: 'add',onPressed: () => incrementCounter(ref), // 👈 抽离的操作方法child: Icon(Icons.add),),const SizedBox(width: 10),FloatingActionButton.small(heroTag: 'reset',onPressed: () => resetCounter(ref), // 👈 抽离 reset 方法child: Icon(Icons.refresh),),],),);}
}

🧭 对比总结
项目ProviderRiverpod
状态类ChangeNotifierStateNotifier<int>
状态读取Provider.of()ref.watch()
状态变更notifyListeners()state = ...
UI绑定StatelessWidget + ProviderConsumerWidget
生命周期控制依赖 Widget Tree独立容器控制(ProviderScope)

🧭 8. 最佳实践建议

建议理由或说明
使用 StateNotifier 替代 ChangeNotifier更轻量、更明确、更好测试
避免直接 ref.read().state++推荐封装方法防止状态逻辑混乱
拆分 Provider 文件提高可读性和可维护性
ref.read() 写到方法中避免在 UI 中写业务逻辑

📦 附加资源推荐

  • 官方文档:https://riverpod.dev
  • IDE 插件:Riverpod Snippets
  • 推荐组合:Riverpod + go_router + freezed + dio

源码地址

📚 Flutter 状态管理系列文章目录
  1. Flutter 状态管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux)

  2. setState() 使用详解:原理及注意事项

  3. InheritedWidget 组件使用及原理

  4. Flutter 中 Provider 的使用、注意事项与原理解析(含代码实战)

  5. GetX 用法详细解析以及注意事项

  6. Flutter BLoC 使用详细解析

  7. Flutter MobX 响应式原理与实战详解

  8. Flutter Riverpod 使用详细解析

  9. Riverpod原理解析(实现一个自己的Riverpod

关键字:注册深圳公司流程_外贸网站建站多少钱_销售网站排名_电商平台怎么推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: