当前位置: 首页 > news >正文

Flutter实现局部刷新的几种方式

目录

前言

1.局部刷新的重要性

1.概念

2.重要性

2.局部刷新实现的几种方式

1.使用setState方法进行局部刷新

2.使用StatefulWidget和InheritedWidget局部刷新UI

3.ValueNotifier和ValueListenableBuilder

4.StreamBuilder

5.Provider

6.GetX

7.使用GlobalKey


前言

       在 Flutter 中,状态管理指的是如何管理和更新应用中的数据状态,并且根据状态的变化来更新 UI。有效的状态管理能够帮助开发者创建更高效、更可维护的应用。

        setState是 Flutter 中最基本的状态管理方法,当状态发生变更的时候,会通知框架重新构建UI。当然我们知道当我们调用setState方法的时候,页面会重绘,当页面布局比较复杂的时候,有时候我们仅仅需要更新某个单独的UI,这个时候如果使用setState方法,则会有比较大的性能消耗去重绘当前页面UI.

        那么Flutter中有哪些方法可以局部刷新UI呢,这篇博客列举了Flutter实现局部刷新的几种方式。

1.局部刷新的重要性

1.概念

        局部刷新指的是只刷新界面的一部分,而不是整个页面。这样可以提高性能和用户体验。

2.重要性

  1. 避免不必要的重绘,提高性能
  2. 提供更流畅的用户体验
  3. 减少资源消耗

2.局部刷新实现的几种方式

1.通过setState局部刷新

        setState是Flutter 中最常用的状态管理方法,用于通知框架状态发生变化,导致界面重建。

        我们创建Flutter工程的时候,系统默认生成的计时器的例子,就是setState局部刷新的例子。

import 'package:flutter/material.dart';class StatePartialRefreshPage extends StatefulWidget {const StatePartialRefreshPage({super.key});@overrideState<StatePartialRefreshPage> createState() =>_StatePartialRefreshPageState();
}class _StatePartialRefreshPageState extends State<StatePartialRefreshPage> {int _count = 0;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("setState局部刷新",style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14),),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('您点击了$_count次',style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),),const SizedBox(height: 20,),FilledButton(onPressed: () {setState(() {_count++;});},child: const Icon(Icons.add)),],)),);}
}

        图1.setState局部刷新

         当页面比较简单的时候,可以直接使用setState方法局部刷新UI。

        使用场景:简单的状态变化,如按钮点击计数、开关状态等。

        注意事项:

  1. 频繁调用 setState 可能导致性能问题
  2. 避免在 build 方法中调用 setState 

2.使用StatefulWidget和InheritedWidget局部刷新UI

        StatefulWidget 是具有状态的组件,InheritedWidget 用于在组件树中共享数据。

        当我们需要共享数据的时候,可以考虑StatefulWidget和InheritedWidget局部刷新UI.

        完整代码如下:

        图2.共享数据的方式刷新UI

import 'package:flutter/material.dart';class MyInheritedWidget extends InheritedWidget {final int counter;const MyInheritedWidget({super.key,required this.counter,required super.child,});@overridebool updateShouldNotify(covariant InheritedWidget oldWidget) {return true;}static MyInheritedWidget? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();}
}class InheritedWidgetPage extends StatefulWidget {final String title;const InheritedWidgetPage({super.key, required this.title});@overrideState<InheritedWidgetPage> createState() => _InheritedWidgetPageState();
}class _InheritedWidgetPageState extends State<InheritedWidgetPage> {int counter = 0;void _incrementCounter() {setState(() {counter++;});}@overrideWidget build(BuildContext context) {return MyInheritedWidget(counter: counter,child: Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: Column(children: [const Divider(),const CounterDisplay(),const SizedBox(height: 20),ElevatedButton(onPressed: _incrementCounter,child: const Text('add'),),],),),),);}
}class CounterDisplay extends StatelessWidget {const CounterDisplay({super.key});@overrideWidget build(BuildContext context) {final inheritedWidget = MyInheritedWidget.of(context);return Text('点击次数: ${inheritedWidget?.counter}');}
}

        这种方式主要使用场景如下:组件树中共享状态时,如主题、语言设置等。

        优点就是数据共享方便,代码简介

        缺点就是使用复杂,性能可能收到影响

3.ValueNotifier和ValueListenableBuilder

        ValueNotifier 是一个简单的状态管理工具,ValueListenableBuilder 用于监听 ValueNotifier 的变化。

        使用方法也非常简单:

        1.实例化ValueNotifier

        2.要监听的Widget对象是用ValueListenableBuilder包裹起来

        3.事件触发数据的变更方法

        这种方式和前几种方式比较非常的简单易容,性能也很高

        缺点:只能处理简单的状态变化

        完整的代码如下:

import 'package:flutter/material.dart';class ValueNotifierPage extends StatefulWidget {final String title;const ValueNotifierPage({super.key, required this.title});@overrideState<ValueNotifierPage> createState() => _ValueNotifierPageState();
}class _ValueNotifierPageState extends State<ValueNotifierPage> {final ValueNotifier<int> _counter = ValueNotifier<int>(0);@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: ValueListenableBuilder<int>(valueListenable: _counter,builder: (context, value, child) {return Text('您点击了$value次',style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold),);},)),floatingActionButton: FloatingActionButton(child: const Icon(Icons.add),onPressed: () {_counter.value ++;},));}
}

4.StreamBuilder

        Stream是一种用于传递异步事件的对象,可以通过StreamController发送事件。在需要刷新UI的地方,可以发送一个事件到Stream,然后使用StreamBuilder监听该Stream,当收到新的事件时,StreamBuilder会自动重新构建UI。这种方式适用于需要监听多个异步事件的情况。

        当我们需要处理异步数据流,如网络请求、实时数据等的时候,可以考虑使用StreamBuilder。例如在下面的例子中,我们写了一个模拟网络请求的异步方法,当网络请求没返回正确结果的时候,我们可以加载进度条。

        这种方式的优点就是可以对异步请求进行更加精准的控制,例如网络请求的状态等。却迪奥就是复杂度比较高,可能需要更多的代码。        

        完整的代码如下:

import 'dart:async';
import 'package:flutter/material.dart';class StreamBuilderRefreshUIPage extends StatefulWidget {final String title;const StreamBuilderRefreshUIPage({super.key, required this.title});@overrideState<StreamBuilderRefreshUIPage> createState() =>_StreamBuilderRefreshUIPageState();
}class _StreamBuilderRefreshUIPageState extends State<StreamBuilderRefreshUIPage> {late Future<String> _data;Future<String> fetchData() async {// 模拟网络请求延迟await Future.delayed(const Duration(seconds: 2));// 返回模拟数据return 'Hello, Flutter!';}@overridevoid initState() {// TODO: implement initStatesuper.initState();_data = fetchData();}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: FutureBuilder<String>(future: _data,builder: (context, snapshot) {if (snapshot.connectionState == ConnectionState.waiting) {return const CircularProgressIndicator();} else if (snapshot.hasError) {return Text('Error: ${snapshot.error}');} else {return Text('Data: ${snapshot.data}');}},),),floatingActionButton: FloatingActionButton(onPressed: fetchData,tooltip: 'Increment',child: const Icon(Icons.add),),);}
}

5.Provider

       Provider 是 Flutter 推荐的状态管理解决方案,Consumer 用于读取和监听状态。

        我们还以定时器为例。

        1.首先我们导入Provider.

provider: ^6.1.2

        2.自定义ChangeNotifier类。

        ChangeNotifier 是 Flutter SDK 中的一个简单的类。它用于向监听器发送通知。换言之,如果被定义为 ChangeNotifier,你可以订阅它的状态变化。(这和大家所熟悉的观察者模式相类似)。

        在我们要实现的代码中,有两个变量_counter1和_counter2.代码定义如下:

class CounterModel extends ChangeNotifier {int _counter1 = 0;int _counter2 = 0;void addCounter1(){debugPrint('counter:$_counter1');_counter1 += 1;notifyListeners();}void addCounter2(){debugPrint('counter:$_counter2');_counter2 += 1;notifyListeners();}
}

        3.使用Customer把我们要刷新的Widget包裹起来

            Consumer<CounterModel>(builder: (context, counterModel, child) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Text('计数器1个数: ${counterModel._counter1}'),ElevatedButton(onPressed: (){counterModel.addCounter1();}, child: const Icon(Icons.add),),],);},),

        4.完整代码如下:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';class ProviderRefreshPage extends StatefulWidget {final String title;const ProviderRefreshPage({super.key, required this.title});@overrideState<ProviderRefreshPage> createState() => _ProviderRefreshPageState();
}class CounterModel extends ChangeNotifier {int _counter1 = 0;int _counter2 = 0;void addCounter1(){debugPrint('counter:$_counter1');_counter1 += 1;notifyListeners();}void addCounter2(){debugPrint('counter:$_counter2');_counter2 += 1;notifyListeners();}
}class _ProviderRefreshPageState extends State<ProviderRefreshPage> {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[const SizedBox(height: 10,), // 添加一些间距const Divider(),const Text('计数器实例',style: TextStyle(fontSize: 12,fontWeight: FontWeight.bold),),Consumer<CounterModel>(builder: (context, counterModel, child) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Text('计数器1个数: ${counterModel._counter1}'),ElevatedButton(onPressed: (){counterModel.addCounter1();}, child: const Icon(Icons.add),),],);},),Consumer<CounterModel>(builder: (context, counterModel, child) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Text('计数器1个数: ${counterModel._counter2}'),ElevatedButton(onPressed: (){counterModel.addCounter2();}, child: const Icon(Icons.add),),],);},),const Divider(height: 20,),],),),);}
}

6.GetX

        我们还可以使用GetX实现UI的局部刷新。

        首先安装GetX:

get: ^4.6.6

        然后我们把变量封装在GetxController中.

class CounterManagerController extends GetxController {final counter1 = 0.obs;final counter2 = 0.obs;void incrementCount1() {counter1.value++;}void incrementCount2() {counter2.value++;}
}

        再使用Obx把需要显示逻辑的Widget包裹起来。

Obx(()=> Text('计数器1个数: ${controller.counter2.value}'))

        完整的代码如下:

import 'package:flutter/material.dart';
import 'package:get/get.dart';class CounterManagerController extends GetxController {final counter1 = 0.obs;final counter2 = 0.obs;void incrementCount1() {counter1.value++;}void incrementCount2() {counter2.value++;}
}class GetXRefreshUIPage extends StatelessWidget {final String title;const GetXRefreshUIPage({super.key, required this.title});@overrideWidget build(BuildContext context) {final CounterManagerController controller = Get.put(CounterManagerController());return Scaffold(appBar: AppBar(title: Text(title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[const SizedBox(height: 10,), // 添加一些间距const Divider(),const Text('计数器实例',style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold),),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Obx(()=> Text('计数器1个数: ${controller.counter1.value}')),ElevatedButton(onPressed: () {controller.incrementCount1();},child: const Icon(Icons.add),),],),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [Obx(()=> Text('计数器1个数: ${controller.counter2.value}')),ElevatedButton(onPressed: () {controller.incrementCount2();},child: const Icon(Icons.add),),],),const Divider(height: 20,),],),),);}
}

        当然GetX中实现局部刷新的方式还有其它几种写法,大家可以看一下它的文档。这里只是提供了其中的一种实现思路。

7.通过GlobalKey局部刷新

        上述三种实现方式都是通过框架实现的,如果你不想导入这个框架,我们可以使用GlobalKey来实现UI的局部刷新功能。

        在整个应用程序中是唯一的Key GlobalKey可以唯一标识元素,GlobalKey提供了对这些元素相关联的访问,比如BuildContext。对于StatefulWidgets,GlobalKey也提供对State的访问。

       在我们的计时器的demo中,如果我们通过GlobalKey的方式局部刷新UI,首先我们把要局部刷新的Widget提出来,单独封装成一个组件。

        完整代码如下,我们封装要局部刷新的Widget,并且提供一个刷新内部数据的接口,onPressed.

class CounterText extends StatefulWidget {const CounterText(Key key) : super(key: key);@overrideState<StatefulWidget> createState() {return CounterTextState();}
}class CounterTextState extends State<CounterText> {String _text="0";@overrideWidget build(BuildContext context) {return Center(child: Text(_text,style: const TextStyle(fontSize: 20),),);}void onPressed(int count) {setState(() {_text = count.toString();});}
}

        然后在我们的主界面实例化GlobaKey:

  int _count   = 0;int _count2  = 0;GlobalKey<CounterTextState> textKey = GlobalKey();GlobalKey<CounterTextState> textKey2 = GlobalKey();    

            在需要刷新UI的事件中,通过GlobalKey调用上一步提供的接口,刷新即可。

        完整代码如下:

import 'package:flutter/material.dart';class GlobalKeyRefreshPage extends StatefulWidget {final String title;const GlobalKeyRefreshPage({super.key, required this.title});@overrideState<GlobalKeyRefreshPage> createState() => _GlobalKeyRefreshPageState();
}class _GlobalKeyRefreshPageState extends State<GlobalKeyRefreshPage> {int _count   = 0;int _count2  = 0;
//包裹你定义的需要更新的weightGlobalKey<CounterTextState> textKey = GlobalKey();GlobalKey<CounterTextState> textKey2 = GlobalKey();@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title:  Text(widget.title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.start,children: <Widget>[const SizedBox(height: 10,), // 添加一些间距const Divider(),const Text('计数器实例',style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold),),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [CounterText(textKey),ElevatedButton(onPressed: () {_count++;textKey.currentState?.onPressed(_count);},child: const Icon(Icons.add),),],),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [CounterText(textKey2),ElevatedButton(onPressed: () {_count2++;textKey2.currentState?.onPressed(_count2);},child: const Icon(Icons.add),),],),const Divider(height: 20,),],),),);}
}class CounterText extends StatefulWidget {const CounterText(Key key) : super(key: key);@overrideState<StatefulWidget> createState() {return CounterTextState();}
}class CounterTextState extends State<CounterText> {String _text="0";@overrideWidget build(BuildContext context) {return Center(child: Text(_text,style: const TextStyle(fontSize: 20),),);}void onPressed(int count) {setState(() {_text = count.toString();});}
}

相关文章:

Flutter实现局部刷新的几种方式

目录 前言 1.局部刷新的重要性 1.概念 2.重要性 2.局部刷新实现的几种方式 1.使用setState方法进行局部刷新 2.使用StatefulWidget和InheritedWidget局部刷新UI 3.ValueNotifier和ValueListenableBuilder 4.StreamBuilder 5.Provider 6.GetX 7.使用GlobalKey 前言 …...

力扣题解(回文子串)

647. 回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 思路&#xff1a; 首先&#xff0c;本题要求的是数目&#xff0c;而且不要求没…...

对数的基本概念

概念 在数学中&#xff0c;对数是对求幂的逆运算&#xff0c;正如除法是乘法的倒数&#xff0c;反之亦然。这意味着一个数字的对数是必须产生过另一个固定数字(基数)的指数 如果a的x次方等于N&#xff08;a > 0, 且a不等于1&#xff09;&#xff0c;那么数x叫做以a为底N的…...

C双指针滑动窗口算法

这也许是双指针技巧的最⾼境界了&#xff0c;如果掌握了此算法&#xff0c;可以解决⼀⼤类⼦字符串匹配的问题 原理 1、我们在字符串 S 中使⽤双指针中的左右指针技巧&#xff0c;初始化 left right 0&#xff0c;把索引闭区间 [left, right] 称为⼀个「窗⼝」。 2、我们先…...

WPF学习(6) -- WPF命令和通知

一 、WPF命令 1.ICommand代码 创建一个文件夹和文件 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input;namespace 学习.Command {public class MyCommand : ICommand{Acti…...

升级到LVGL9的一些变化(后续发现再补充)

目录 一、主要内容 二、新增内容 三、常规API变化 四、Display API(显示API) 五、其他 最近在将LVGL8的demo代码升级到LVGL9,带来不小的变化 ,收集网上的一些内容,整理如下: 一、主要内容 二、新增内容 三、常规API变化 四、Display API(显示API)...

当在多线程环境中使用 C++进行编程时,怎样确保线程安全以及如何处理线程之间的同步和通信?

在C中确保线程安全性和处理线程之间的同步和通信有多种方法。下面是一些常用的技术和技巧&#xff1a; 互斥锁&#xff1a;使用互斥锁可以确保只有一个线程可以访问共享资源。在访问共享资源之前获取锁&#xff0c;在完成后释放锁。这可以防止多个线程同时访问同一份数据&#…...

博物馆地图导航系统:高精度地图引擎与AR/VR融合,实现博物馆数字化转型

在人民日益追求精神文化的时代下&#xff0c;博物馆作为传承与展示人类文明的璀璨殿堂&#xff0c;其重要性不言而喻。然而&#xff0c;随着博物馆规模的不断扩大和藏品种类的日益丰富&#xff0c;游客在享受知识盛宴的同时&#xff0c;也面临着“迷路”与“错过”的困扰。博物…...

liunx作业笔记1

一、选择题&#xff08;每小题2分&#xff0c;共20分&#xff09; 1、下列变量命名为Shell中无效变量名的是&#xff08; D &#xff09; A、v_ar1 B、var1 C、_var D、*var 变量名以字母开头&#xff0c;包含下划线和数字。 2、关于expr命令的使用下列命令中得数不等于…...

大话C语言:第31篇 指针和数组的关系

数组在内存中是连续存放的&#xff0c;其名称代表了数组首元素的首地址&#xff0c;该地址是常量&#xff0c; 也就是一个指向数组首元素的指针。因此&#xff0c;指针和数组有着密切的关系&#xff1a; 可以使用指针来访问和操作数组中的元素。通过指针的算术运算&#xff0c;…...

Mysql-索引应用

目录 索引应用 MySQL有哪些索引? 普通索引和唯一索引有什么区别? 哪个更新性能更好? 、 聚簇索引的主键索引怎么设置? 追问:假如你不设置会怎么样? 我们一般选择什么样的字段来建立索引? 索引越多越好吗? 索引怎么优化? &#xff08;覆盖索引优化、防止索引失效、…...

Facebook 开源计算机视觉 (CV) 和 增强现实 (AR) 框架 Ocean

Ocean 是一个独立于平台的框架&#xff0c;支持所有主要操作系统&#xff0c;包括 iOS、Android、Quest、macOS、Windows 和 Linux。它旨在彻底改变计算机视觉和混合现实应用程序的开发。 Ocean 主要使用 C 编写&#xff0c;包括计算机视觉、几何、媒体处理、网络和渲染&#x…...

【接口自动化_13课_接口自动化总结】

一、自我介绍 二、项目介绍 自己的职责、项目流程 1&#xff09;功能测试&#xff0c;怎么设计用例的--测试策略 2&#xff09;功能测试为什么还有代码实现&#xff0c;能用工具实现&#xff0c;为什么还用代码实现。 基本情况 项目名称:项目类型&#xff1a;项目测试人员…...

安防管理平台LntonCVS视频汇聚融合云平台智慧火电厂安全生产管理应用方案

中国的电力产业作为国民经济发展的重要能源支柱&#xff0c;被视为国民经济的基础产业之一。目前&#xff0c;我国主要依赖火力发电&#xff0c;主要燃料包括煤炭、石油和天然气等&#xff0c;通过燃烧转化为动能&#xff0c;再转变为电能输送至全国各地。火力发电量占全国发电…...

【Web性能优化】在Vue项目中使用defer优化白屏,秒加载!

历史小剧场 相对而言&#xff0c;流芳千古的钱谦益先生&#xff0c;就有点儿区别了&#xff0c;除了家产外&#xff0c;也很能挣钱&#xff08;怎么来的就别说了&#xff09;&#xff0c;经常出没红灯区&#xff0c;六十岁多了&#xff0c;还娶了柳如是&#xff0c;明朝亡时&am…...

springboot上传图片

前端的name的值必须要和后端的MultipartFile 形参名一致 存储本地...

python入门:python及PyCharm安装

前言 我们将详细介绍如何在系统上安装Python及使用PyCharm创建项目的具体流程。Python是一种广泛应用的编程语言&#xff0c;其简单易学的特点使其成为初学者的首选。而PyCharm则是一个功能强大的Python IDE&#xff0c;可以极大地提高开发效率。通过本文&#xff0c;你将学会…...

链接追踪系列-04.linux服务器docker安装elk

[rootVM-24-17-centos ~]# cat /proc/sys/vm/max_map_count 65530 [rootVM-24-17-centos ~]# sysctl -w vm.max_map_count262144 vm.max_map_count 262144 #先创建出相应目录&#xff1a;/opt/dockerV/es/…docker run -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -d -p 92…...

深入探讨微服务架构设计模式与常见实践

深入探讨微服务架构设计模式与常见实践 引言 在现代软件开发中&#xff0c;微服务架构因其灵活性和可扩展性被广泛采用。本文将深入探讨微服务架构的设计理念和常见模式&#xff0c;详细介绍每个模式的实现方法&#xff0c;并分别提供适用于Ubuntu和CentOS的具体命令和代码示…...

【java】合并数组的两种方法

文章目录 1.利用arraycope的方法2.将两数组合并 &#xff0c;在排序 1.利用arraycope的方法 public class MergeArr {public static void main(String[] args) {int[] arr1 {1,2,3,4,5,6};int[] arr2 {7,8,9};//合并完的数组int[] arr3 new int[arr1.length arr2.length];…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...