在 Avalonia 开发中,导航功能是构建多页面应用的核心需求。Avalonia 无需依赖第三方库,仅通过内置控件与 MVVM 模式即可实现灵活的页面切换。本文将以 “基础导航” 为核心,从 ViewModel 与 View 设计、导航逻辑实现,到样式美化与响应式交互,完整拆解一个多页面 Avalonia 应用的开发流程。

一、核心原理:Avalonia 导航的实现逻辑

Avalonia 实现导航的核心思路是 “控件绑定 + 视图模型切换”

  1. 核心控件:使用 TransitioningContentControl 作为页面容器,该控件支持内容切换时的过渡效果,且可直接绑定到 ViewModel 中的属性。
  2. 状态管理:在主视图模型(如 MainWindowViewModel)中定义 _currentPage 属性(类型为 ViewModelBase),通过更新该属性的值,触发 TransitioningContentControl 加载对应的视图。
  3. View-ViewModel 匹配:借助 Avalonia 的 ViewLocator(通常在项目初始化时自动配置),框架会根据 _currentPage 的具体 ViewModel 类型,自动匹配并加载对应的 View(视图)。

二、分步实现:从 ViewModel 到 View 的开发

1. 定义页面 ViewModel

首先创建两个业务页面的 ViewModel(继承自项目基础类 ViewModelBase),分别对应 “颜色列表页” 和 “关于页”。

(1)ColorsViewModel:颜色列表视图模型

该 ViewModel 负责加载系统颜色、处理颜色数据转换(如 RGB 转 CMYK),并通过响应式命令触发数据初始化。

using Avalonia.Data.Converters;
using Avalonia.Media;
using ReactiveUI.SourceGenerators;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;namespace BasicRoutingExample.ViewModels
{public partial class ColorsViewModel : ViewModelBase{// 响应式属性:当前选中的颜色名称与颜色值[Reactive]private string? _colorName;[Reactive]private Color? _color;// 颜色转换器:将 Color 类型转为 CMYK 格式字符串(静态属性,直接复用)public static FuncValueConverter<Color, string> ToCMYK { get; } = new(color =>{double r = color.R / 255.0;double g = color.G / 255.0;double b = color.B / 255.0;double k = 1 - Math.Max(Math.Max(r, g), b);double C = k < 1 ? (1 - r - k) / (1 - k) : 0;double M = k < 1 ? (1 - g - k) / (1 - k) : 0;double Y = k < 1 ? (1 - b - k) / (1 - k) : 0;return $"C={Math.Round(C * 100, 1)}% M={Math.Round(M * 100, 1)}% Y={Math.Round(Y * 100, 1)}% K={Math.Round(k * 100, 1)}%";});// 颜色列表数据源public ObservableCollection<ColorsViewModel> Colors { get; } = [];// 无参构造函数(用于框架实例化)public ColorsViewModel() { }// 响应式命令:初始化颜色列表(加载 Avalonia 内置颜色)[ReactiveCommand]private void Init(){// 反射获取 Avalonia.Media.Colors 中的所有静态颜色属性var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public).Where(p => p.PropertyType == typeof(Color));foreach (var property in colorProperties){if (property.GetValue(null) is Color color){Colors.Add(new ColorsViewModel{Color = color,ColorName = property.Name // 颜色名称(如 "Red"、"Blue")});}}}}
}
2)AboutViewModel:关于页视图模型

该 ViewModel 主要提供应用基础信息(名称、版本、描述),通过反射获取程序集信息。

using System.Reflection;namespace BasicRoutingExample.ViewModels
{public partial class AboutViewModel : ViewModelBase{// 应用名称(从当前程序集获取)public string? AppName => Assembly.GetExecutingAssembly().GetName().Name;// 应用版本(从当前程序集获取)public string? Version => Assembly.GetExecutingAssembly().GetName()?.Version?.ToString();// 应用描述信息public string Message => "这是基于 Avalonia 框架开发的应用,集成 ReactiveUI 实现响应式交互。";}
}

2. 设计页面 View(视图)

View 采用 XAML 编写,通过数据绑定关联对应的 ViewModel,实现 “数据驱动视图”。

(1)ColorsView:颜色列表视图

通过 ItemsControl 展示颜色列表,搭配 ColorToHexConverter 和自定义的 ToCMYK 转换器,实现颜色的多格式展示。

<UserControl xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:vm="using:BasicRoutingExample.ViewModels"xmlns:b="using:BasicRoutingExample.Behaviors"xmlns:cv="using:Avalonia.Controls.Converters"mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="560"x:DataType="vm:ColorsViewModel"<!-- 页面加载时执行 Init 命令,初始化颜色数据 -->b:LoadedBehavior.ExecuteCommandOnLoaded="{Binding InitCommand}"x:Class="BasicRoutingExample.Views.ColorsView"> <!-- 资源定义:颜色转 16 进制字符串转换器 --><UserControl.Resources><cv:ColorToHexConverter x:Key="ColorToHex" AlphaPosition="Leading" IsAlphaVisible="False"/>			</UserControl.Resources><!-- 布局:顶部标题 + 滚动列表 --><Grid RowDefinitions="Auto,*"><!-- 标题:显示颜色总数 --><TextBlock Text="{Binding Colors.Count, StringFormat='Avalonia 系统颜色 ({0}种)'}" FontSize="18" Margin="5"/><!-- 滚动列表:展示所有颜色 --><ScrollViewer Grid.Row="1"><ItemsControl ItemsSource="{Binding Colors}"><ItemsControl.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal" Spacing="10" Margin="5"><!-- 颜色预览块 --><Rectangle Width="300" Height="30"><Rectangle.Fill><SolidColorBrush Color="{Binding Color}"/></Rectangle.Fill></Rectangle><!-- 颜色名称 --><TextBlock Text="{Binding ColorName}" Width="110"/><!-- 16 进制颜色值(使用内置转换器) --><TextBlock Text="{Binding Color, Converter={StaticResource ColorToHex}, ConverterParameter={x:True}}" Width="80"/><!-- CMYK 颜色值(使用 ViewModel 中的静态转换器) --><TextBlock Text="{Binding Color, Converter={x:Static vm:ColorsViewModel.ToCMYK}}"/></StackPanel></DataTemplate></ItemsControl.ItemTemplate></ItemsControl></ScrollViewer></Grid>
</UserControl>
(2)AboutView:关于页视图

简洁展示应用名称、版本和描述,通过网格布局实现内容对齐。

<UserControl xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:vm="using:BasicRoutingExample.ViewModels"mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="560"x:DataType="vm:AboutViewModel"x:Class="BasicRoutingExample.Views.AboutView"> <!-- 布局:两行网格,分别展示“应用信息”和“描述” --><Grid RowDefinitions="Auto,Auto"><!-- 应用名称 + 版本 --><StackPanel Orientation="Horizontal" Spacing="5" Grid.Row="0"><TextBlock Text="{Binding AppName}" FontWeight="Bold" FontSize="24"/><TextBlock Text="{Binding Version}" FontSize="20"/></StackPanel><!-- 应用描述 --><TextBlock Text="{Binding Message}" Grid.Row="1" FontSize="18"Margin="0,10,0,0"/></Grid>
</UserControl>

3. 实现主窗口导航逻辑

主窗口的 ViewModel(MainWindowViewModel)负责管理页面切换状态,通过响应式命令触发导航,并通过属性监听实现按钮 “选中态” 同步。

MainWindowViewModel:导航核心逻辑
using Microsoft.Extensions.DependencyInjection;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using System.Reactive.Linq;namespace BasicRoutingExample.ViewModels
{public partial class MainWindowViewModel : ViewModelBase{// 核心导航属性:当前显示的页面 ViewModel[Reactive]private ViewModelBase? _currentPage;    // 导航命令:跳转到“颜色列表页”[ReactiveCommand]private void GotoColors(){// 避免重复切换同一页面if (CurrentPage is not ColorsViewModel){// 从 IOC 容器获取 ColorsViewModel 实例CurrentPage = App.Current.Services?.GetRequiredService<ColorsViewModel>();}}// 导航命令:跳转到“关于页”[ReactiveCommand]private void GotoAbout(){// 避免重复切换同一页面if (CurrentPage is not AboutViewModel){// 从 IOC 容器获取 AboutViewModel 实例CurrentPage = App.Current.Services?.GetRequiredService<AboutViewModel>();}}// 构造函数:初始化默认页面,并监听页面切换状态public MainWindowViewModel(){// 初始页面设为“颜色列表页”CurrentPage = App.Current.Services?.GetRequiredService<ColorsViewModel>();// 监听 CurrentPage 变化,同步“颜色页选中态”_isColorsPage = this.WhenAnyValue(x => x.CurrentPage).Select(x => x?.GetType() == typeof(ColorsViewModel)).ToProperty(this, x => x.IsColorsPage);// 监听 CurrentPage 变化,同步“关于页选中态”_isAboutPage = this.WhenAnyValue(x => x.CurrentPage).Select(x => x?.GetType() == typeof(AboutViewModel)).ToProperty(this, x => x.IsAboutPage);}// 页面选中态属性(用于按钮样式绑定)private readonly ObservableAsPropertyHelper<bool> _isColorsPage;private readonly ObservableAsPropertyHelper<bool> _isAboutPage;public bool IsColorsPage => _isColorsPage.Value;public bool IsAboutPage => _isAboutPage.Value;}
}

4. 配置 IOC 容器(依赖注入)

为了实现 ViewModel 的解耦与复用,通过 Microsoft.Extensions.DependencyInjection 配置 IOC 容器,在应用启动时注册 ViewModel 实例。

App.axaml.cs:应用启动与 IOC 配置
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
using BasicRoutingExample.ViewModels;
using BasicRoutingExample.Views;
using Microsoft.Extensions.DependencyInjection;
using System;namespace BasicRoutingExample
{public partial class App : Application{// 应用初始化:加载 XAML 资源public override void Initialize(){AvaloniaXamlLoader.Load(this);            }// 框架初始化完成:配置 IOC 并启动主窗口public override void OnFrameworkInitializationCompleted(){// 移除默认数据验证插件(避免不必要的验证逻辑)BindingPlugins.DataValidators.RemoveAt(0);// 配置 IOC 服务Services = ConfigureServices();// 启动桌面应用主窗口if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop){desktop.MainWindow = new MainWindow{DataContext = new MainWindowViewModel(), // 为主窗口绑定 ViewModel};}            base.OnFrameworkInitializationCompleted();}// 静态属性:获取当前应用实例public new static App Current => (App)Application.Current!;// IOC 服务容器public IServiceProvider? Services { get; private set; }// 配置 IOC 服务:注册 ViewModel(瞬态模式,每次获取新实例)private static ServiceProvider ConfigureServices(){var services = new ServiceCollection();services.AddTransient<ColorsViewModel>();services.AddTransient<AboutViewModel>();return services.BuildServiceProvider();}}
}

三、样式美化:实现响应式按钮与全局样式

通过 Avalonia 的样式系统,为按钮添加 “默认态”“ hover 态”“选中态”,并统一全局控件样式(如文本、边框)。

1. 全局样式配置(App.axaml)

<Application xmlns="https://github.com/avaloniaui"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"x:Class="BasicRoutingExample.App"xmlns:local="using:BasicRoutingExample"RequestedThemeVariant="Default"> <!-- 跟随系统主题(浅色/深色) --><!-- View-ViewModel 匹配器:自动根据 ViewModel 加载 View --><Application.DataTemplates><local:ViewLocator/></Application.DataTemplates><!-- 资源定义:颜色、渐变等可复用资源 --><Application.Resources><!-- 主色调 --><SolidColorBrush x:Key="PrimaryBackground">#14172D</SolidColorBrush><SolidColorBrush x:Key="PrimaryForeground">#cfcfcf</SolidColorBrush><!-- 渐变背景 --><LinearGradientBrush x:Key="PrimaryGradient" StartPoint="0%,0%" EndPoint="100%,0%"><GradientStops><GradientStop Offset="0" Color="#111214"/><GradientStop Offset="1" Color="#151E3E"/></GradientStops></LinearGradientBrush><!-- 交互状态颜色 --><SolidColorBrush x:Key="PrimaryHoverBackground">#333853</SolidColorBrush><SolidColorBrush x:Key="PrimaryHoverForeground">White</SolidColorBrush><SolidColorBrush x:Key="PrimaryActiveBackground">#334488</SolidColorBrush><SolidColorBrush x:Key="PrimaryActiveForeground">AliceBlue</SolidColorBrush></Application.Resources><!-- 全局控件样式 --><Application.Styles><!-- 基础主题(Fluent 风格) --><FluentTheme />	<!-- 文本框默认样式 --><Style Selector="TextBlock"> <Setter Property="Foreground" Value="{StaticResource PrimaryForeground}"/><Setter Property="VerticalAlignment" Value="Center"/></Style><!-- 标题文本样式(用于页面标题) --><Style Selector="TextBlock.caption"> <Setter Property="FontSize" Value="28"/><Setter Property="HorizontalAlignment" Value="Center"/><Setter Property="VerticalAlignment" Value="Center"/></Style><!-- 菜单边框样式 --><Style Selector="Border.menu"> <Setter Property="Background" Value="{StaticResource PrimaryGradient}"/><Setter Property="Padding" Value="10"/></Style><!-- 内容区域边框样式 --><Style Selector="Border.client"> <Setter Property="Padding" Value="10"/><Setter Property="Background" Value="{StaticResource PrimaryBackground}"/></Style><!-- 按钮基础样式 --><Style Selector="Button"> <Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="Width" Value="150"/></Style><!-- 按钮默认态 --><Style Selector="Button /template/ContentPresenter">						<Setter Property="Background" Value="Transparent"/><Setter Property="Foreground" Value="{StaticResource PrimaryForeground}"/><Setter Property="FontSize" Value="18"/>			</Style><!-- 按钮 hover 态(鼠标悬浮) --><Style Selector="Button:pointerover /template/ContentPresenter"><Setter Property="Background" Value="{StaticResource PrimaryHoverBackground}"/><Setter Property="Foreground" Value="{StaticResource PrimaryHoverForeground}"/></Style><!-- 按钮选中态(当前页面对应的按钮) --><Style Selector="Button.active /template/ContentPresenter"><Setter Property="Background" Value="{StaticResource PrimaryActiveBackground}"/><Setter Property="Foreground" Value="{StaticResource PrimaryActiveForeground}"/></Style></Application.Styles>
</Application>

2. 导航按钮实现(主窗口 XAML 片段)

通过 Classes.active 绑定 IsColorsPage/IsAboutPage 属性,实现 “选中态” 自动切换;通过 Command 绑定导航命令,触发页面跳转。

<!-- 颜色列表页按钮 -->
<Button Command="{Binding GotoColorsCommand}" Classes.active="{Binding IsColorsPage}"><StackPanel Orientation="Horizontal" Spacing="15"><Image Source="/Assets/images/colors.png" Width="32"/><TextBlock Text="颜色列表"/></StackPanel>
</Button><!-- 关于页按钮 -->
<Button Command="{Binding GotoAboutCommand}" Classes.active="{Binding IsAboutPage}"><StackPanel Orientation="Horizontal" Spacing="15"><Image Source="/Assets/images/aboutA.png" Width="32"/><TextBlock Text="关于应用"/></StackPanel>
</Button>

四、关键技巧与优化建议

1. 轻量转换器 FuncValueConverter 的优势

Avalonia 提供的 FuncValueConverter 无需创建单独的转换器类,可直接在 ViewModel 中定义为静态属性,减少代码冗余。例如本文中 RGB 转 CMYK 的转换器,直接通过 x:Static 引用即可使用:

<TextBlock Text="{Binding Color, Converter={x:Static vm:ColorsViewModel.ToCMYK}}"/>

2. 页面切换的性能优化

  • 避免重复实例化:在导航命令中添加判断(如 CurrentPage is not ColorsViewModel),防止同一页面被重复创建。
  • 选择合适的 IOC 生命周期:本文使用 AddTransient(瞬态模式,每次获取新实例),若需保留页面状态,可改为 AddSingleton(单例模式)或 AddScoped(作用域模式)。

3. 响应式框架的选择

  • ReactiveUI:适合复杂交互场景,支持属性监听、响应式命令,但需要编写较多模板代码(如 ObservableAsPropertyHelper 相关逻辑)。
  • CommunityToolkit.Mvvm:语法更简洁,通过 [ObservableProperty] [RelayCommand] 等特性减少样板代码,适合快速开发。

五、总结

本文通过一个完整的示例,展示了 Avalonia 基础导航的实现流程:从 ViewModel 设计(数据与命令)、View 布局(XAML 与数据绑定),到导航逻辑(_currentPage 属性管理)、样式美化(响应式按钮与全局样式)。核心要点包括:

  1. 利用 TransitioningContentControl 与 _currentPage 绑定实现页面切换;
  2. 通过 IOC 容器实现 ViewModel 的解耦与实例管理;
  3. 借助样式系统与属性监听,实现交互状态(如按钮选中态)的自动同步。

掌握这些基础后,可进一步扩展功能,例如添加页面切换动画、参数传递、导航历史记录等,构建更复杂的 Avalonia 多页面应用。

运行效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96792.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96792.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/96792.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UniApp 分包异步化配置及组件引用解决方案

具体参考微信小程序文档基础能力 / 分包加载 / 分包异步化 一、分包页面组件配置 在 UniApp 的pages.json中&#xff0c;为分包页面&#xff08;或主包如 tabbar 页面&#xff09;配置异步组件时&#xff0c;需同时设置usingComponents和componentPlaceholder&#xff1a; {&…

系统核心解析:深入操作系统内部机制——进程管理与控制指南(一)【进程/PCB】

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨个人…

微论-神经网络特征空间的动态聚集,对抗灾难性遗忘的新范式

这是一个非常有趣且富有想象力的理论构想。受陀螺仪启发&#xff0c;我将陀螺仪的“定轴性”与“进动性”原理引入神经网络的特征空间&#xff0c;探讨一种对抗灾难性遗忘的新范式。---### **基于陀螺仪原理的神经网络记忆巩固理论探讨**#### **引言&#xff1a;记忆的流失与稳…

鸿蒙审核问题——折叠屏展开态切换时,输入框内容丢失

文章目录背景解决历程1、无意中发现了眉目2、确定问题原因3、解决办法4、官方文档5、总结背景 奇葩的事情年年有啊&#xff0c;今年特别多。这不今天又遇到了一个奇葩的问题。鸿蒙NextAPP上架AppGallery市场&#xff0c;审核拒了&#xff0c;说是折叠屏手机展开态切换时&#…

前后端分离架构中,Node.js的底层实现原理与线程池饥饿问题解析

在VueJava/.NET的前后端分离架构中&#xff0c;Node.js的底层实现原理与线程池饥饿问题解析 一、架构概述&#xff1a;Node.js的定位与角色 在现代Web开发中&#xff0c;Vue.js作为前端框架与Java/.NET后端结合的架构非常流行。在这种架构中&#xff0c;Node.js通常扮演着两个关…

Django ModelForm:快速构建数据库表单

Django 中的 forms.ModelForm —— 它是 Django 表单系统和 ORM 的一个“桥梁”&#xff0c;能帮助你快速基于 数据库模型&#xff08;Model&#xff09; 自动生成表单&#xff0c;极大减少重复代码。1. 什么是 ModelForm 普通 Form (forms.Form)&#xff1a;完全手写字段&…

补 json的作用

&#xff1a;“我开车直接拧钥匙就能走&#xff0c;为什么还要看仪表盘和用中控台&#xff1f;”直接点击“运行”&#xff0c;就像是汽车的自动驾驶模式。它能帮你开起来&#xff0c;但你不知道它走的是哪条路&#xff0c;油门踩多深。使用 launch.json 配置&#xff0c;就像是…

apache详细讲解(apache介绍+apache配置实验+apache实现https网站)

1.apache HTTP server介绍httpd项目地址:https://httpd.apache.org/ 在Apache2中有三种工作模式&#xff0c;使用者可以根据不同的业务场景来进行选择(1)prefork模式prefork模式是一种老而稳的模式:一个主进程管理者多个子进程&#xff0c;每个子进程单独处理用户请求&#xf…

jajajajajajajava

线程1 线程概念进程:进程指正在内存中运行的程序。进程具有一定的独立性。线程:线程是进程中的一个执行单元。负责当前进程中程序的执行。一个进程中至少有一个线程。如果一个进程中有多个线程&#xff0c;称之为多线程程序。java中的线程采用的是抢占式调度&#xff0c;如果线…

虚拟机CentOS里JDK的安装与环境配置

---本文以JDK17为例---步骤 1&#xff1a;进入/tmp临时目录# 进入临时目录 cd /tmp步骤 2&#xff1a;下载 Java 17 安装包wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.9%2B9/OpenJDK17U-jdk_x64_linux_hotspot_17.0.9_9.tar.gz步骤 3&am…

mybatis-plus多租户兼容多字段租户标识

默认租户插件处理器的缺陷 在springboot工程中引入mybatis-plus的租户插件TenantLineInnerInterceptor&#xff0c;能简化我们的数据隔离操作&#xff0c;例如各类含租户用户登录权限的rest接口中&#xff0c;不需要再根据登录用户-set租户条件-触发查询&#xff0c;租户插件能…

HBase高级特性(布隆过滤器和协处理器)、列族设计、rowkey设计以及热点问题处理

在阐述HBase高级特性和热点问题处理前&#xff0c;首先回顾一下HBase的特点&#xff1a;分布式、列存储、支持实时读写、存储的数据类型都是字节数组byte[]&#xff0c;主要用来处理结构化和半结构化数据&#xff0c;底层数据存储基于hdfs。 同时&#xff0c;HBase和传统数据库…

redis sentinel 与 clauster 的区别

Redis Sentinel(哨兵)和Redis Cluster(集群)是Redis提供的两种不同的高可用和扩展性解决方案,它们的设计目标和适用场景有显著区别: 1. 核心功能与目标 Redis Sentinel 主要解决主从架构的高可用问题,实现自动故障转移 监控主从节点状态,当主节点故障时自动将从节点提…

MySQL数据库中快速导入大数据sql

1.PwerShell命令页面导入全表数据库 -P3310 指定数据库端口号Get-Content "本地sql文件目录" | .\mysql -u root -p -P 33102.PwerShell命令页面导入单表到数据库 -P3310 指定数据库端口号Get-Content "本地sql文件目录" | .\mysql -u root -p -P 3310 数…

消息类型proto的编写和生成

消息类型proto的编写和生成 代码如下&#xff1a; syntax"proto3"; package xypmq;enum ExchangeType {UNKNOWNTYPE0;DIRECT1;FANOUT2;TOPIC3; };enum DeliveryMode {UNKNOWNMODE0;UNDURABLE1;DURABLE2; };message BasicProperties {string id1;DeliveryMode deliver…

Vuetify:构建优雅Vue应用的Material Design组件库

Vuetify是一个基于Material Design设计规范的Vue.js UI组件库&#xff0c;它提供了80多个精心设计的组件&#xff0c;帮助开发者快速构建美观且功能丰富的企业级应用。核心特性1. 完整的Material Design实现// 所有组件遵循Material Design规范 <v-btn color"primary&q…

SpringBoot 注解深剖:@RequestParam 与 @RequestBody 的终极对决,90% 的开发者都踩过这些坑!

在 SpringBoot 开发中&#xff0c;处理 HTTP 请求参数是我们每天都要面对的工作。而RequestParam和RequestBody这两个注解&#xff0c;就像是我们手中的两把利剑&#xff0c;既能高效解决问题&#xff0c;用不好也可能 "误伤" 自己。作为一名资深 Java 开发者&#x…

【Docker】P2 Docker环境构建准备:MacOS 与 Linux

目录操作系统与 Docker 的兼容性分析Docker 技术本质MacOS 环境下的 Docker 构建1. 安装前准备2. Docker Desktop安装3. 镜像加速配置高级操作&#xff1a;文件共享配置Linux 环境下的 Docker 构建卸载历史版本配置软件源Docker 核心组件安装系统服务配置镜像加速器配置应用配置…

OpenCV 发票识别全流程:透视变换与轮廓检测详解

目录 前言 一、核心技术原理&#xff1a;透视变换与轮廓检测 1. 透视变换&#xff1a;让倾斜发票 “正过来” &#xff08;1&#xff09;什么是透视变换&#xff1f; &#xff08;2&#xff09;透视变换的 5 个关键步骤 2. 轮廓检测&#xff1a;精准定位发票区域 &#x…

并发:使用volatile和不可变性实现线程安全

《Java并发编程实战》中的VolatileCachedFactorizer展示了如何使用volatile和不可变性来实现线程安全。解决了简单缓存实现中可能出现的线程安全问题&#xff0c;同时避免了全量同步带来的性能开销。 场景背景 假设有一个服务&#xff08;如因数分解服务&#xff09;&#xff0…