Flutter 中的数据跨层传递方案
在 Flutter 中,数据跨层传递(从父组件向子组件传递数据,或从子组件向父组件传递)有多种方案,主要包括以下几种:
1. 直接参数传递(Constructor 参数)
适用场景:
- 父组件向子组件传递数据,适用于层级关系较浅的情况。
示例:
class ParentWidget extends StatelessWidget {final String message = "Hello from Parent";Widget build(BuildContext context) {return ChildWidget(message: message);}
}class ChildWidget extends StatelessWidget {final String message;const ChildWidget({required this.message});Widget build(BuildContext context) {return Text(message);}
}
✅ 优点:简单、直观。
❌ 缺点:如果层级较深,可能需要逐层传递,导致“参数传递链”问题。
2. InheritedWidget(Flutter 低级状态管理方案)
适用场景:
- 子 Widget 跨层共享父 Widget 的属性,且数据不会频繁更新。
示例:
class MyDataProvider extends InheritedWidget {final String data;const MyDataProvider({required this.data, required Widget child}) : super(child: child);static MyDataProvider? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<MyDataProvider>();}bool updateShouldNotify(covariant MyDataProvider oldWidget) {return oldWidget.data != data;}
}class ParentWidget extends StatelessWidget {Widget build(BuildContext context) {return MyDataProvider(data: "Hello from InheritedWidget",child: ChildWidget(),);}
}class ChildWidget extends StatelessWidget {Widget build(BuildContext context) {final provider = MyDataProvider.of(context);return Text(provider?.data ?? "No data");}
}
✅ 优点:数据可在组件树中被多个组件访问,无需手动传递。
❌ 缺点:手写较繁琐,通常与 ChangeNotifier 或 Provider 结合使用。
3. Provider(推荐)
适用场景:
- 全局状态管理,适用于多个页面共享数据的情况。
示例:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';class CounterProvider with ChangeNotifier {int count = 0;void increment() {count++;notifyListeners();}
}void main() {runApp(ChangeNotifierProvider(create: (_) => CounterProvider(),child: MyApp(),),);
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(home: CounterPage(),);}
}class CounterPage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Provider Example")),body: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text("Count: ${context.watch<CounterProvider>().count}"),ElevatedButton(onPressed: () {context.read<CounterProvider>().increment();},child: Text("Increment"),),],),);}
}
✅ 优点:官方推荐、简洁、支持自动通知 UI 更新。
❌ 缺点:需要引入 provider 包。
4. Riverpod(增强版 Provider)
适用场景:
- 需要更强的依赖注入和状态管理能力,避免
Provider的嵌套问题。
示例:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';final counterProvider = StateProvider<int>((ref) => 0);void main() {runApp(ProviderScope(child: MyApp()));
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(home: CounterPage(),);}
}class CounterPage extends ConsumerWidget {Widget build(BuildContext context, WidgetRef ref) {final count = ref.watch(counterProvider);return Scaffold(appBar: AppBar(title: Text("Riverpod Example")),body: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text("Count: $count"),ElevatedButton(onPressed: () => ref.read(counterProvider.notifier).state++,child: Text("Increment"),),],),);}
}
✅ 优点:比 Provider 更简洁、更强大,避免 context 依赖问题。
❌ 缺点:学习成本较高,需要使用 flutter_riverpod 包。
5. GetX(轻量级但强大的状态管理)
适用场景:
- 想要减少模板代码,并需要更高性能的状态管理。
示例:
import 'package:flutter/material.dart';
import 'package:get/get.dart';class CounterController extends GetxController {var count = 0.obs;void increment() => count++;
}void main() {runApp(GetMaterialApp(home: CounterPage()));
}class CounterPage extends StatelessWidget {final CounterController controller = Get.put(CounterController());Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("GetX Example")),body: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Obx(() => Text("Count: ${controller.count}")),ElevatedButton(onPressed: controller.increment,child: Text("Increment"),),],),);}
}
✅ 优点:无需 context,代码简洁,性能高。
❌ 缺点:非官方方案,项目可能不易维护。
6. EventBus(跨组件间事件通信)
适用场景:
- 非父子组件之间传递数据,比如 多个页面或多个独立的组件 之间通信。
示例:
import 'package:event_bus/event_bus.dart';final EventBus eventBus = EventBus();class DataEvent {final String data;DataEvent(this.data);
}// 发送事件
eventBus.fire(DataEvent("Hello EventBus"));// 监听事件
eventBus.on<DataEvent>().listen((event) {print(event.data);
});
✅ 优点:适合全局事件通信,避免组件嵌套传参。
❌ 缺点:管理不当可能导致事件滥用,影响代码可读性。
7. Notification(从子组件向父组件传递数据)
适用场景:
- 适用于 子组件向父组件发送事件通知,常用于 滚动监听、交互事件 等情况。
示例
子组件 发送 CustomNotification,父组件 监听 并接收通知:
import 'package:flutter/material.dart';// 自定义通知类
class CustomNotification extends Notification {final String message;CustomNotification(this.message);
}class NotificationExample extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Notification Example")),body: NotificationListener<CustomNotification>(onNotification: (notification) {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("收到通知: ${notification.message}")),);return true; // 返回 true,表示已处理通知},child: ChildWidget(),),);}
}class ChildWidget extends StatelessWidget {Widget build(BuildContext context) {return Center(child: ElevatedButton(onPressed: () {CustomNotification("Hello, Parent!").dispatch(context);},child: Text("发送通知"),),);}
}void main() {runApp(MaterialApp(home: NotificationExample()));
}
解析
NotificationListener<CustomNotification>监听 子组件ChildWidget发送的CustomNotification事件。CustomNotification("Hello, Parent!").dispatch(context);从子组件向上传递通知,并触发onNotification方法。ScaffoldMessenger.of(context).showSnackBar(...)在父组件显示通知。
✅ 优点:
- 适合 从子组件向上 传递事件,而无需父组件主动监听或传递回调函数。
- 无需 Provider、全局状态,适用于简单的事件通知。
❌ 缺点:
- 不适合传递复杂数据(比如全局状态)。
- 仅能向上级组件传递,不能横向或全局广播数据。
使用场景
- 子组件通知父组件某些事件发生(如按钮点击、用户输入变化)。
- 监听滚动事件(
ScrollNotification)。 - 监听输入框变化(
FormField自带FormFieldState)。
总结
| 方案 | 方向 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 构造函数传参 | 父 → 子 | 普通数据传递 | 简单直观 | 层级深时麻烦 |
| InheritedWidget | 父 → 子 | 共享数据但不频繁变更 | 内置方案 | 代码较复杂 |
| Provider ✅ | 全局 | 官方推荐,适合全局状态 | 易用高效 | 需要第三方库 |
| Riverpod | 全局 | 更强大的依赖管理 | 简单、无 context 限制 | 学习成本 |
| GetX | 全局 | 轻量级状态管理 | 代码简洁,性能好 | 非官方方案 |
| EventBus | 任意 | 跨组件通信 | 适合全局事件 | 可能滥用 |
| Notification | 子 → 父 | 子组件通知父组件 | 无需回调,适合单向事件 | 仅支持向上传递 |
✅ 结论:
- 状态管理:推荐
Provider/Riverpod。 - 子 → 父传递:
Notification(事件通知),或者直接 回调(Function)。 - 轻量级方案:
GetX(简洁),或者 直接StatefulWidget维护本地状态。
相关文章:
Flutter 中的数据跨层传递方案
在 Flutter 中,数据跨层传递(从父组件向子组件传递数据,或从子组件向父组件传递)有多种方案,主要包括以下几种: 1. 直接参数传递(Constructor 参数) 适用场景: 父组件向…...
代码随想录D50-51 图论 Python
理论基础 理论基础部分依然沿用代码随想录教程中的介绍: 图的种类 度 连通性 连通性用于表示图中节点的连通情况。 如果有节点不能到达其他节点,则为非连通图,想象将多个水分子表示为图,不考虑非键作用,这张图就不是…...
MyBatis进阶
日志的使用 我们在使用MyBatis的时候, 其实MyBatis框架会打印一些必要的日志信息, 在开发阶段这些日志信息对我们分析问题,理解代码的执行是特别有帮助的; 包括项目上线之后,我们也可以收集项目的错误日志到文件里面去; 所以我们采用专门的日志系统来处理. 步骤 导入坐标拷贝…...
容器化部署Kafka的最佳实践:基于KRaft模式的无ZooKeeper方案
一、docker 部署kafka单节点 1.1安装docker 可以参考这篇CentOS 7安装docker并配置镜像加速 1.3 运行kafka(注意修改zookeeper,kafka地址) docker run -d --name kafka -e KAFKA_ADVERTISED_LISTENERSPLAINTEXT://172.16.10.180:9092 -p …...
DeepSeek核心算法解析:如何打造比肩ChatGPT的国产大模型
注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 DeepSeek大模型技术系列一DeepSeek核心算法解析:如何…...
LeetCode-633. 平方数之和
1、题目描述 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 b2 c 。 示例 1: 输入:c 5 输出:true 解释:1 * 1 2 * 2 5示例 2: 输入:c 3 输出:f…...
前端面试技巧与实践
在当今快速发展的互联网行业中,前端开发已经成为了一个至关重要的角色。随着技术的不断进步和用户需求的日益复杂,前端工程师的职责不再仅仅是实现页面的布局和交互,而是需要具备全方位的技术能力和工程思维。根据2023年Stack Overflow的开发…...
windows Redis Insight 如何查看宝塔docker里的redis数据
1、ping 命令用于测试网络连通性,它只需要目标 IP 地址作为参数,不需要端口号。正确的命令如下: ping 公网地址2、使用 Telnet 测试端口连通性 telnet 公网地址 端口 telnet 47.108.67.228 6379如果连接成功,窗口会变为空白&am…...
sql数据执行失败,三个命令依次执行
set global innodb_strict_mode off set global.sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION; set sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION;...
BGP配置华为——RR反射器配置
实验拓扑 与之前实验同理将loop0作为routerID使用,且R1和R2上用loop1接口用于模拟用户其他网段 实验要求 1,在AS100内运行OSPF协议 2.配置路由反射器,使得从R1进入的数据能够反射到全局网络 3.在R1和R2上分别宣告自己的loop1口网段用于观…...
基于Flask的艺恩影片票房分析系统的设计与实现
【Flask】基于Flask的艺恩影片票房分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统利用Python编程语言进行后端开发,结合Echarts进行数据的可视化展示&a…...
架构设计系列(三):架构模式
一、概述 关于移动应用开发中常见的架构模式,这些模式是为了克服早期模式的局限性而引入。常见的 架构模式有: MVC, MVP, MVVM, MVVM-C, and VIPER 二、MVC, MVP, MVVM, MVVM-C, and VIPER架构模式 MVC、MVP、MVVM、MVVM-C 和 VIPER 是移动应用开发中…...
零基础学QT、C++(一)安装QT
目录 如何快速学习QT、C呢? 一、编译器、项目构建工具 1、编译器(介绍2款) 2、项目构建工具 二、安装QT 1、下载QT安装包 2、运行安装包 3、运行QT creator 4、导入开源项目 总结 闲谈 如何快速学习QT、C呢? 那就是项目驱动法&…...
SQL注入(SQL Injection)详解与实战
文章目录 一、什么是SQL注入?二、常见SQL注入类型三、手动注入步骤(以CTF题目为例)四、CTF实战技巧五、自动化工具:SQLMap六、防御措施七、CTF例题八、资源推荐 一、什么是SQL注入? SQL注入是一种通过用户输入构造恶意…...
【Prometheus】prometheus结合domain_exporter实现域名监控
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...
Java 设计模式之命令模式
文章目录 Java 设计模式之命令模式概述UML代码实现简单实现复杂实现 Java 设计模式之命令模式 概述 命令模式(Command):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可…...
BT401双模音频蓝牙模块如何开启ble的透传,有什么注意事项
BT401音频蓝牙模块如何开启ble的透传? 首先BT401的蓝牙音频模块,分为两个版本,dac版本和iis数字音频版本 DAC版本:就是BT401蓝牙模块【9和10脚】直接输出模拟音频信号,也就是说,直接推动耳机可以听到声音 …...
利用二分法+布尔盲注、时间盲注进行sql注入
一、布尔盲注: import requestsdef binary_search_character(url, query, index, low32, high127):while low < high:mid (low high 1) // 2payload f"1 AND ASCII(SUBSTRING(({query}),{index},1)) > {mid} -- "res {"id": payloa…...
Vue 项目登录的基本流程
Vue 用户登录的基本流程包括以下6个步骤: 步骤: 1. 创建登录表单 在前端,首先要创建一个登录表单,用户输入账号(用户名、邮箱、手机号等)和密码。 示例:Login.vue <template><div…...
kubernetes源码分析 kubelet
简介 从官方的架构图中很容易就能找到 kubelet 执行 kubelet -h 看到 kubelet 的功能介绍: kubelet 是每个 Node 节点上都运行的主要“节点代理”。使用如下的一个向 apiserver 注册 Node 节点:主机的 hostname;覆盖 host 的参数࿱…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
