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

优化 Flutter 应用开发:探索 ViewModel 的威力

介绍

1.1 什么是 ViewModel?

ViewModel,顾名思义,就是视图的模型。在 Flutter 中,ViewModel 是一种用于管理视图状态和业务逻辑的重要概念。它承载了应用程序的核心功能,像是一个精心设计的控制中心,负责连接视图和数据模型,使得应用程序能够顺畅地运行。

想象一下,当你在手机上点击一个按钮时,背后发生了什么?按钮按下后,应用程序可能需要从服务器获取数据、更新用户界面、保存用户操作等等。这些复杂的任务需要一个地方来统一管理,而这个地方就是 ViewModel。它像是一个灵活的中介者,负责处理用户交互和数据流动,让应用程序保持良好的状态和流畅的运行。

1.2 ViewModel 的作用和重要性

ViewModel 的作用是多方面的,它扮演了多个角色:

  • 管理视图状态:ViewModel 负责管理视图的状态,例如加载状态、错误状态、空数据状态等。它使得视图能够根据不同的状态显示不同的UI,提升用户体验。

  • 处理业务逻辑:ViewModel 包含了应用程序的业务逻辑,例如数据处理、网络请求、数据持久化等。它将业务逻辑从视图中分离出来,使得代码更加清晰和易于维护。

  • 与视图交互:ViewModel 通过与视图绑定来更新UI,例如通过 ChangeNotifier 实现状态监听,使得视图能够实时响应数据变化,保持界面的一致性和及时性。

因此,ViewModel 的重要性不言而喻。它是应用程序的核心架构之一,直接影响着应用程序的性能、可维护性和用户体验。

1.3 为什么在 Flutter 中需要 ViewModel?

在 Flutter 中,视图和业务逻辑通常紧密耦合在一起,这导致了一些问题:

  • 代码混乱:视图代码和业务逻辑混杂在一起,使得代码难以理解和维护。
  • 难以测试:由于视图和业务逻辑耦合在一起,使得单元测试变得困难,无法有效地测试业务逻辑。
  • 重复代码:相似的业务逻辑可能被重复实现在多个视图中,导致了代码的冗余和低效。

因此,引入 ViewModel 架构可以解决这些问题:

  • 分离关注点:ViewModel 将视图和业务逻辑分离,使得代码更加清晰和模块化,易于理解和维护。
  • 提升可测试性:ViewModel 可以单独进行单元测试,保证业务逻辑的正确性,提升了代码的质量和稳定性。
  • 提高重用性:ViewModel 可以被多个视图共享和重用,避免了重复实现相似的业务逻辑,提高了代码的复用率和可维护性。

因此,引入 ViewModel 架构是为了提升 Flutter 应用程序的可维护性、可测试性和用户体验,使得应用程序更加健壮和易于开发。

Flutter 中的状态管理概述

2.1 基本概念:State、StatefulWidget、ChangeNotifier 等

在 Flutter 中,状态管理是构建应用程序的关键部分。让我们先来了解一些基本概念:

  • State:状态是指应用程序中可能会变化的数据或信息,例如用户输入、网络响应、UI状态等。在 Flutter 中,状态通常被封装在 State 对象中,并由 StatefulWidget 来管理和更新。

  • StatefulWidget:StatefulWidget 是一个可变的组件,它可以根据不同的状态显示不同的UI。它包含一个对应的 State 对象,用于管理组件的状态和生命周期。

  • ChangeNotifier:ChangeNotifier 是 Flutter 提供的一个简单的状态管理类,它实现了一个发布-订阅模式,可以通知依赖它的组件进行更新。通常与 Provider 结合使用,用于构建可重用的状态管理解决方案。

2.2 常见的状态管理方案:setState、Provider、GetX、Riverpod 等

在 Flutter 中,有许多不同的状态管理方案可供选择,每种方案都有其自己的特点和适用场景:

  • setState:setState 是 Flutter 最基本的状态管理方案之一,它通过调用 setState 方法来更新组件的状态,并触发重新构建UI。虽然简单易用,但在大型应用程序中会导致代码冗余和复杂性增加。

  • Provider:Provider 是一个轻量级的状态管理库,它基于 InheritedWidget 和 ChangeNotifier 实现了依赖注入和状态通知。它具有简单、灵活、易于使用等特点,适用于中小型应用程序的状态管理。

  • GetX:GetX 是一个功能丰富的状态管理库,它提供了状态管理、路由管理、依赖注入等功能。它具有简洁、高性能、易于集成等特点,适用于需要快速开发的中大型应用程序。

  • Riverpod:Riverpod 是一个基于 Provider 的新一代状态管理库,它引入了更强大的依赖注入和异步操作支持。它具有类型安全、易于测试、灵活性高等特点,适用于复杂的大型应用程序。

每种状态管理方案都有其适用的场景和优缺点,开发者可以根据项目需求和个人偏好选择合适的方案。无论选择哪种方案,都需要考虑到项目的规模、复杂度和团队的技术水平,以及未来的可扩展性和维护性。

ViewModel 的设计原则

3.1 单一职责原则

在设计 ViewModel 时,我们要遵循单一职责原则,就像给一个人分配一个明确的任务一样。这意味着每个 ViewModel 应该专注于处理一个特定的功能或领域,而不是包揽所有的任务。

想象一下,如果一个人既要负责做饭又要负责洗衣服和打扫卫生,那么可能会出现混乱和效率低下的情况。同样地,一个 ViewModel 如果承担了太多的责任,就会变得臃肿和难以维护。

因此,我们应该将功能分解,每个 ViewModel 只负责一个明确的功能或领域,这样可以使得代码更加清晰、模块化和易于扩展。

3.2 数据驱动原则

ViewModel 的设计应该是数据驱动的,就像汽车的方向盘决定了汽车的前进方向一样。这意味着 ViewModel 应该根据数据的变化来驱动视图的更新,而不是直接操作UI元素。

想象一下,如果一个人不知道目的地在哪里,那么无论如何操作方向盘都不会有意义。同样地,一个 ViewModel 如果没有数据驱动,而是直接操作UI元素,那么就会导致代码混乱和耦合性增加。

因此,我们应该让数据成为驱动力,ViewModel 应该根据数据的变化来更新视图,保持代码的清晰和一致性。

3.3 可测试性原则

ViewModel 的设计应该具有良好的可测试性,就像一个产品经理提出的需求可以被快速验证一样。这意味着我们应该设计 ViewModel,使得它可以轻松地进行单元测试,验证其功能的正确性和稳定性。

想象一下,如果一个产品的功能无法被快速验证,那么可能会导致产品质量下降和用户体验差。同样地,一个无法进行单元测试的 ViewModel,可能会隐藏着许多潜在的问题和风险。

因此,我们应该设计 ViewModel,使其具有良好的单元测试覆盖率,保证其功能的正确性和稳定性,从而提高代码的质量和可维护性。

ViewModel 的实现方式

4.1 使用 Provider 实现 ViewModel

Provider 是 Flutter 中常用的状态管理库之一,它提供了简单而强大的状态管理功能,可以用来实现 ViewModel。使用 Provider 实现 ViewModel 的步骤如下:

  1. 创建 ViewModel 类:编写一个继承自 ChangeNotifier 的 ViewModel 类,定义视图状态和业务逻辑。
  2. 使用 ChangeNotifierProvider 提供 ViewModel:在顶层 Widget 中使用 ChangeNotifierProvider 提供 ViewModel 实例,使得整个应用程序都能访问到 ViewModel。
  3. 在视图中使用 Consumer 或 Provider.of 获取 ViewModel:在需要访问 ViewModel 的地方使用 Consumer 或 Provider.of 获取 ViewModel 实例,并根据需要更新视图。

4.2 使用 GetX 实现 ViewModel

GetX 是一个功能丰富的状态管理库,它提供了状态管理、路由管理、依赖注入等功能,并且使用起来非常简单和方便。使用 GetX 实现 ViewModel 的步骤如下:

  1. 创建 Controller 类:编写一个继承自 GetxController 的 Controller 类,定义视图状态和业务逻辑。
  2. 在视图中使用 GetBuilder 或 Obx 获取 Controller:在需要访问 Controller 的地方使用 GetBuilder 或 Obx 获取 Controller 实例,并根据需要更新视图。

4.3 使用 Riverpod 实现 ViewModel

Riverpod 是一个基于 Provider 的新一代状态管理库,它引入了更强大的依赖注入和异步操作支持。使用 Riverpod 实现 ViewModel 的步骤如下:

  1. 创建 ViewModel 类:编写一个普通的 Dart 类,定义视图状态和业务逻辑。
  2. 使用 Provider 或 ConsumerWidget 提供 ViewModel:在视图中使用 Provider 或 ConsumerWidget 提供 ViewModel 实例,并根据需要更新视图。

4.4 自定义实现 ViewModel

除了使用现有的状态管理库之外,我们还可以自定义实现 ViewModel。这种方式可以根据项目的需求和个人偏好来灵活定制,通常会更加灵活和可控。自定义实现 ViewModel 的步骤如下:

  1. 创建 ViewModel 类:编写一个普通的 Dart 类,定义视图状态和业务逻辑。
  2. 在视图中引入 ViewModel:在需要访问 ViewModel 的地方引入 ViewModel 类,并根据需要更新视图。

无论使用哪种方式实现 ViewModel,都需要考虑到项目的规模、复杂度和团队的技术水平,以及未来的可扩展性和维护性。选择合适的实现方式可以使得代码更加清晰、模块化和易于维护。

这种方式类型安全、易于测试,适用于复杂的大型应用程序的状态管理。

4.4 自定义实现 ViewModel

想象一下你是一个发明家,你可以根据自己的需求和想法设计出自己的工具。自定义实现 ViewModel 就像是你设计自己的工具一样,根据项目需求和个人偏好来实现。

自定义实现 ViewModel 可以根据具体的业务需求来设计,可以使用各种各样的技术和框架,例如使用 BLoC、Redux、MobX 等。这种方式灵活性高,可以根据项目的需求来选择合适的实现方式。

ViewModel 的最佳实践

5.1 如何设计和组织 ViewModel

设计和组织 ViewModel 是开发 Flutter 应用程序的关键步骤之一,它直接影响着代码的清晰度、可维护性和可扩展性。以下是一些最佳实践:

  • 单一职责原则:每个 ViewModel 应该专注于处理一个特定的功能或领域,避免承担过多的责任,使得代码更加清晰和模块化。
  • 分层结构:ViewModel 可以根据功能进行分层组织,例如将 UI 相关的逻辑和业务逻辑分开,使得代码更易于理解和维护。
  • 抽象和接口:使用抽象类和接口来定义 ViewModel 的结构和行为,可以使得代码更加灵活和可扩展。

5.2 ViewModel 与业务逻辑的关系

ViewModel 与业务逻辑之间有着密切的关系,它们相辅相成,共同构建了应用程序的核心功能。以下是一些最佳实践:

  • 业务逻辑的委托:ViewModel 应该将复杂的业务逻辑委托给其他类来处理,使得代码更加清晰和可测试。
  • 数据处理和状态管理:ViewModel 负责管理视图状态和处理数据,例如加载状态、错误状态、数据处理等。
  • 网络请求和数据持久化:ViewModel 可以包含网络请求和数据持久化的逻辑,但应该将其封装成可复用的方法,便于在多个视图中共享和重用。

5.3 ViewModel 与视图的交互方式

ViewModel 与视图之间的交互方式直接影响着应用程序的用户体验和性能。以下是一些最佳实践:

  • 数据驱动视图:ViewModel 应该根据数据的变化来驱动视图的更新,而不是直接操作 UI 元素,这样可以保持代码的清晰和一致性。
  • 状态监听和通知:ViewModel 可以使用状态监听或通知机制来通知视图更新,例如使用 ChangeNotifier 实现状态监听,保证视图能够及时响应数据变化。
  • 事件处理和用户交互:ViewModel 可以处理用户交互和事件响应,例如点击事件、输入事件等,但应该将其封装成可复用的方法,便于在多个视图中共享和重用。

综上所述,设计和组织 ViewModel、与业务逻辑的关系以及与视图的交互方式是开发 Flutter 应用程序时需要考虑的重要因素,合理的设计和实践可以提高代码的质量、可维护性和用户体验。

ViewModel 的案例分析

6.1 构建一个简单的 Flutter 应用程序

让我们从头开始构建一个简单的 Flutter 应用程序,例如一个待办事项列表应用程序。该应用程序包含一个输入框用于添加新的待办事项,以及一个列表用于显示已添加的待办事项。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'todo_list_view_model.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return ChangeNotifierProvider(create: (context) => TodoListViewModel(),child: MaterialApp(title: 'Todo List App',theme: ThemeData(primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: TodoListPage(),),);}
}class TodoListPage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Todo List'),),body: TodoListView(),floatingActionButton: AddTodoButton(),);}
}class TodoListView extends StatelessWidget {Widget build(BuildContext context) {final viewModel = Provider.of<TodoListViewModel>(context);return ListView.builder(itemCount: viewModel.todoList.length,itemBuilder: (context, index) {final todo = viewModel.todoList[index];return ListTile(title: Text(todo),trailing: IconButton(icon: Icon(Icons.delete),onPressed: () => viewModel.removeTodo(index),),);},);}
}class AddTodoButton extends StatelessWidget {Widget build(BuildContext context) {return FloatingActionButton(onPressed: () {showDialog(context: context,builder: (BuildContext context) {final TextEditingController controller = TextEditingController();return AlertDialog(title: Text('Add Todo'),content: TextField(controller: controller,decoration: InputDecoration(hintText: 'Enter your todo'),),actions: <Widget>[TextButton(child: Text('Cancel'),onPressed: () => Navigator.of(context).pop(),),TextButton(child: Text('Add'),onPressed: () {final todo = controller.text;if (todo.isNotEmpty) {Provider.of<TodoListViewModel>(context, listen: false).addTodo(todo);}Navigator.of(context).pop();},),],);},);},tooltip: 'Add Todo',child: Icon(Icons.add),);}
}

6.2 使用 ViewModel 管理应用程序的状态和逻辑

我们可以使用 ViewModel 来管理应用程序的状态和逻辑。在这个案例中,我们创建一个名为 TodoListViewModel 的 ViewModel 类,它负责管理待办事项列表的状态和逻辑。

import 'package:flutter/material.dart';class TodoListViewModel extends ChangeNotifier {List<String> _todoList = [];List<String> get todoList => _todoList;void addTodo(String todo) {_todoList.add(todo);notifyListeners();}void removeTodo(int index) {_todoList.removeAt(index);notifyListeners();}
}

6.3 解决实际项目中的常见问题和挑战

在实际项目中,使用 ViewModel 可以解决许多常见的问题和挑战,例如:

  • 数据管理:ViewModel 可以帮助我们管理应用程序的数据,包括加载数据、保存数据等。
  • 状态管理:ViewModel 可以帮助我们管理应用程序的状态,例如加载状态、错误状态、空数据状态等。
  • 业务逻辑:ViewModel 可以帮助我们管理应用程序的业务逻辑,例如处理用户交互、网络请求、数据处理等。
  • 视图更新:ViewModel 可以帮助我们更新视图,保证视图能够及时响应数据变化,提升用户体验。

在这个案例中,我们使用 ViewModel 来管理待办事项列表的状态和逻辑,使得应用程序更加清晰、模块化和易于维护。同时,ViewModel 还可以帮助我们解决其他实际项目中的常见问题和挑战,提升开发效率和代码质量。

总结

使用 ViewModel 是一种有效地组织和管理应用程序代码的方法,它能够帮助我们优化状态管理、解耦视图和业务逻辑、提升开发效率和增强可测试性,是开发高质量 Flutter 应用程序的重要手段之一。

相关文章:

优化 Flutter 应用开发:探索 ViewModel 的威力

介绍 1.1 什么是 ViewModel&#xff1f; ViewModel&#xff0c;顾名思义&#xff0c;就是视图的模型。在 Flutter 中&#xff0c;ViewModel 是一种用于管理视图状态和业务逻辑的重要概念。它承载了应用程序的核心功能&#xff0c;像是一个精心设计的控制中心&#xff0c;负责…...

Android开发系列(四)Jetpack Compose之Button

在Jetpack Compose中&#xff0c;Button是一个常用的用户界面组件&#xff0c;用于执行某些操作或触发某些事件。Button控件是可触摸的&#xff0c;并且通常会显示一个文本或图标来表示其功能。 要在Jetpack Compose中创建一个Button&#xff0c;可以使用Button()函数&#xf…...

Java17 --- RabbitMQ之插件使用

目录 一、Federation插件 1.1、运行两个rabbitmq实例 1.2、启用插件 1.3、在下游端点添加上游端点 1.4、创建策略 1.6、测试 二、联邦队列 2.1、创建策略 2.2、创建交换机与队列 2.2.1、创建52000的队列与交换机 2.2.2、创建62000的队列 三、Shovel 3.1、启…...

6.18总结

省赛排位赛2&#xff1a; 省赛排名赛2 - Virtual Judge 思路&#xff1a; 设两个方程直接解出来就行 代码&#xff1a; #include<bits/stdc.h> using namespace std; int n, m; int main() {int n, m;int ans1, ans2;cin >> n >> m;ans1 n - (-3 sqr…...

【ARM Cache 及 MMU 系列文章 1.4 -- 如何判断 L3 Cache 是否实现?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Cluster Configuration Register代码实现什么是Single-Threaded Core?什么是PE(Processor Execution units)?Single-Threaded Core与PE的关系对比多线程(Multithreading)Cluster…...

打印mybatis的sql日志

1、application.xml: logging.level.com.xxx.xxx.daodebug2、log4j2.xml: <Logger name"com.xxx.xxx.dao" level"debug" additivity"true" />...

QT day4(对话框 事件机制)

1&#xff1a;思维导图 2&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->setupUi(this);//去除头部this->setWindowFlag(Qt::Frameles…...

序列化与反序列化漏洞实例

实验环境&#xff1a; 本次的序列化与反序列化漏洞为2021年强网杯上的一道比赛题目&#xff0c;我使用phpstudy集成环境将其测试环境搭建在了本地&#xff0c;如下。涉及的几个页面php为&#xff1a; index.php function.php myclass.php index.php : <?php // inde…...

6、while循环 - 习题解析

目录 解析部分&#xff1a;分支练习1244. 请问一个正整数能够整除几次2问题描述解题思路代码实现代码解析 1062. 求落地次数问题描述解题思路代码实现代码解析 1254. 求车速问题描述解题思路代码实现代码解析 1261. 韩信点兵问题描述解题思路代码实现代码解析 解析部分&#xf…...

ReentrantLock可重入锁

可重⼊锁&#xff0c;这个锁可以被线程多次重复进⼊进⾏获取操作。 ReentantLock继承接⼝Lock并实现了接⼝中定义的⽅法&#xff0c;除了能完成synchronized所能完成的所有⼯作 外&#xff0c;还提供了诸如可响应中断锁、可轮询锁请求、定时锁等避免多线程死锁的⽅法。 在并发量…...

如何秒杀系统架构设计

原文路径:https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/%e5%a6%82%e4%bd%95%e8%ae%be%e8%ae%a1%e4%b8%80%e4%b8%aa%e7%a7%92%e6%9d%80%e7%b3%bb%e7%bb%9f/00%20%e5%bc%80%e7%af%87%e8%af%8d%20%e7%a7%92%e6%9d%80%e7%b3%bb%e7%bb%9f%e6%9e%b6%e6%9e%84%e8%ae%be%e8%ae%…...

深度神经网络——什么是降维?

引言 什么是降维&#xff1f; 降维是用于降低数据集维度的过程&#xff0c;采用许多特征并将它们表示为更少的特征。 例如&#xff0c;降维可用于将二十个特征的数据集减少到仅有几个特征。 降维通常用于无监督学习任务 降维是一个用于降低数据集维度的过程&#xff0c;采用许…...

SpringMVC—RequestMapping注解

一、RequestMapping注解 RequestMapping注解&#xff1a;是Spring MVC框架中的一个控制器映射注解&#xff0c;用于将请求映射到相应的处理方法上&#xff0c;具体来说&#xff0c;他可以将指定URL的请求绑定到一个特定的方法或类上&#xff0c;从而实现对请求的处理和响应。 …...

Java线程池基本概念

全局和局部线程池 全局线程池 在Spring框架中&#xff0c;全局线程池如ThreadPoolTaskExecutor通常是作为Spring Bean存在的&#xff0c;它们的生命周期由Spring容器管理。当Spring容器关闭时&#xff0c;这些线程池也会被适当地清理和关闭。因此&#xff0c;开发者通常不需要手…...

智能车联网安全发展形势、挑战

一、技术演进加速车联网安全环境复杂变化 当前&#xff0c;5G、大数据、大算力、大模型等技术正加速在车联网领域实现融合应用。车联网的网络通信能力、感知计算水平以及创新业务应用都在快速发展&#xff0c;与此同时&#xff0c;车联网的网络安全环境也在随之演进变化&#…...

AWS概述

AWS概述EMR Serverless Aamzon Web Services提供了一系列全球范围的云产品&#xff0c;包括计算、存储、数据库、分析、网络、移动、开发工具、管理工具、IoT、安全和企业应用&#xff1a;按需交付、及时可用、采用随用随付的定价模式。你可以畅享200多种服务&#xff0c;从数据…...

MySQL常见面试题自测

文章目录 MySQL基础架构一、说说 MySQL 的架构&#xff1f;二、一条 SQL语句在MySQL中的执行过程 MySQL存储引擎一、MySQL 提供了哪些存储引擎&#xff1f;二、MySQL 存储引擎架构了解吗&#xff1f;三、MyISAM 和 InnoDB 的区别&#xff1f; MySQL 事务一、何谓事务&#xff1…...

c语言回顾-函数递归

1.递归的介绍 1.1什么是递归 递归是指在一个函数的定义中调用自身的过程。简单来说&#xff0c;递归是一种通过重复调用自身来解决问题的方法。 递归包括两个关键要素&#xff1a;基本情况和递归情况。基本情况是指当问题达到某个特定条件时&#xff0c;不再需要递归调用&am…...

消息队列-RabbitMQ-延时队列实现

死信队列 DLX,全称为Dead-Letter-Exchange,死信交换机&#xff0c;死信邮箱。当消息在一个队列中变成死信之后&#xff0c;它能重新发送到另外一个交换器中&#xff0c;这个交换器就是DLX&#xff0c;绑定DLX的队列就称为死信队列。 导致死信的几种原因&#xff1a; ● 消息…...

【热门开源项目推荐】满足不同程序员的需求与关注点

目录 前言一、热门开源项目介绍二、使用开源热门项目的优势&#xff08;一&#xff09;经济方面&#xff08;二&#xff09;技术方面&#xff08;三&#xff09;社区支持及协作方面 三、程序员选择项目模型建议&#xff08;一&#xff09;关键步骤&#xff08;二&#xff09;示…...

一文理清GO语言日志库实现开发项目中的日志功能(rotatelogs/zap分析)

一文理清GO语言日志库实现开发项目中的日志功能&#xff08;rotatelogs/zap分析&#xff09; rotatelogs rotatelogs 是一个用于管理日志文件的 Go 语言库&#xff0c;它提供了自动轮换、压缩和删除旧日志文件的功能。这个库可以帮助你更好地管理和维护你的应用程序日志。要使…...

【Go语言精进之路】构建高效Go程序:了解string实现原理并高效使用

&#x1f525; 个人主页&#xff1a;空白诗 &#x1f525; 热门专栏&#xff1a;【Go语言精进之路】 文章目录 引言一、Go语言的字符串类型1.1 字符串的定义1.2 字符串的零值可用1.3 字符串的不可变性1.4 字符串的拼接1.5 字符串的常用方法1.6 实际使用示例 二、字符串的内部表…...

HDFS 常见命令

在HDFS创建文件夹&#xff1a;hdfs dfs -mkdir /test 复制本地文件到HDFS中某个目录下&#xff1a;hdfs dfs -put /本地路径 /hdfs 路径 查看文件内容&#xff1a;hdfs dfs -cat /test.txt 查看当前文件夹目录&#xff1a;hdfs dfs -ls / 查看文件夹中的文件数&#xff1a;…...

示例:WPF中应用Grid的SharedSizeGroup设置整齐的布局

一、目的&#xff1a;应用Grid的SharedSizeGroup设置整齐的布局 二、实现 <ItemsControl ItemsSource"{local:GetStudents Count5}"><ItemsControl.ItemTemplate><DataTemplate><Grid ShowGridLines"True"><Grid.ColumnDefinit…...

React的form表单自定义校验规则

使用antd开发的过程中&#xff0c;必定会遇到需要对form表单进行必填校验的处理&#xff0c;正常情况下&#xff0c;我们都会一个空的必填校验&#xff0c;如下&#xff1a;一般我们只需要简单配置rules即可 <FormItem label"管理员姓名" {...itemLayout.wholeLi…...

一种新的一维时间序列信号盲解卷积算法(以旋转机械故障诊断为例,MATLAB环境)

一种新的一维时间序列信号盲解卷积算法&#xff08;以旋转机械故障诊断为例&#xff0c;MATLAB环境&#xff09;&#xff0c;可作为深度学习信号前处理过程&#xff0c;水个SCI不是问题。 机械设备的状态信号中往往蕴含着大量的设备异常信息。如何从繁多的机械状态信号中提取足…...

618电商是社区网站入局的好时机吗?

近日&#xff0c;随着618大促的临近&#xff0c;许多内容平台像B站、小红书等纷纷被电商活动所充斥&#xff0c;让用户感觉仿佛被电商绑架一般。这种用户体验的极度不佳让人开始思考&#xff0c;难道这就是互联网社区的未来发展方向吗&#xff1f; 在所有平台性质的社区中&…...

不知道密码,一样能卸载瑞星esm防病毒终端安全防护系统

离开单位后试图卸载瑞星的时候却发现还需要密码&#xff0c;真是烦死了。研究了几分钟后找到了完美卸载方法。 首先&#xff0c;让我们请出老流氓360安全卫士&#xff0c;下载好它&#xff0c;让右键菜单出现使用 360强力删除这一选项。 之后&#xff0c;进入安全模式&#x…...

Chromium 开发指南2024 Mac篇-安装和配置depot_tools工具(三)

1.引言 在前两篇指南中&#xff0c;我们详细介绍了在 macOS 环境下编译 Chromium 所需的硬件要求和系统依赖&#xff0c;并具体讲解了如何正确安装和配置 Xcode。通过这些步骤&#xff0c;您已经为编译 Chromium 打下了坚实的基础。然而&#xff0c;编译 Chromium 还需要配置一…...

微信小程序-路由和页面跳转API

一.wx.navigateTo wx.navigateTo是通过编程实现页面跳转&#xff0c;和navigator组件组件中&#xff0c;open-type"navigate"属性类似&#xff0c;是保留当前页面跳转新的页面&#xff0c;不适用tabbar页面。 //保留当前页面&#xff0c;跳转到非tabbar页面wx.navig…...

陕西最新疫情最新消息/湖南seo优化排名

Burp Suite是什么 Burp Suite 是用于攻击web 应用程序的集成平台。它包含了许多Burp工具&#xff0c;这些不同的burp工具通过协同工作&#xff0c;有效的分享信息&#xff0c;支持以某种工具中的信息为基础供另一种工具使用的方式发起攻击。 它主要用来做安全性渗透测试&#…...

企业做网站的费用/推广平台网站

源&#xff1a;JNA调用DLL 介绍 给大家介绍一个最新的访问本机代码的Java框架—JNA。 JNA(Java Native Access)框架是一个开源的Java框架&#xff0c;是SUN公司主导开发的&#xff0c;建立在经典的JNI的基础之上的一个框架。 JNA项目地址&#xff1a;https://jna.dev.java.net/…...

大连城建设计研究院网站/深圳外包网络推广

1. 什么是gcc gcc的全称是GNU Compiler Collection&#xff0c;它是一个能够编译多种语言的编译器。最开始gcc是作为C语言的编译器&#xff08;GNU C Compiler&#xff09;&#xff0c;现在除了c语言&#xff0c;还支持C、java、Pascal等语言。gcc支持多种硬件平台。 2. gcc的特…...

优秀网页界面设计/西安分类信息seo公司

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理 本文章来自腾讯云 作者&#xff1a;Python知识大全 想要学习Python&#xff1f;有问题得不到第一时间解决&#xff1f;来看看这里“1039649593”满足你的…...

网店怎么开电子发票/汕头seo

一、絮言几名昨晚有幸认识了一个地产朋友&#xff0c;斯文的外表一点也看不出强大的能量。吃饭、喝茶聊开了&#xff0c;认人佩服得不得了&#xff1b;也终于明白他为何地产做得那么成功。他学识很丰富&#xff0c;文学、美学、哲学信手拈来。倒不是因我学理&#xff0c;对此一…...

极验验证+wordpress/网站外链是什么

参考链接 转自 拓宽视野 - 基于ubuntu 18.04 dockerfile 文件内执行条件语句 bash下的Dockerfile FROM ubuntu:18.04RUN ln -fs /bin/bash /bin/sh #切换 sh 为bashRUN if [ -d "/opt/" ]; \then \export START普通; \else \echo "不存在"; \fi \&…...