MAUI与Blazor共享一套UI,媲美Flutter,实现Windows、macOS、Android、iOS ...

火影  金牌会员 | 2022-6-23 23:10:53 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 601|帖子 601|积分 1803

1. 前言

距离上次发《MAUI初体验:爽》一文已经过去2个月了,本计划是下半年或者明年再研究MAUI的,现在计划提前啦,因为我觉得MAUI Blazor挺有意思的:在Android、iOS、macOS、Windows之间共享UI,一处UI增加或者修改,就能得到一致的UI体验。
看看这篇文章《Blazor Hybrid/MAUI 简介和实战》对MAUI Blazor的说明:
MAUI
.NET 多平台应用程序 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用程序, 使用 .net MAUI,可以开发可在 Android、iOS、macOS 上运行的应用,Windows 以及从单个共享代码库运行的应用。
Blazor Hybrid 应用和 .NET MAUI
Blazor Hybrid 支持内置于 .NET 多平台应用 UI (.NET MAUI) 框架。 .NET MAUI 包含 BlazorWebView 控件,该控件运行将 Razor 组件呈现到嵌入式 Web View 中。 通过结合使用 .NET MAUI 和 Blazor,可以跨移动设备、桌面设备和 Web 重复使用一组 Web UI 组件。
今天就分享如何在Blazor Server、Blazor Wasm、MAUI Blazor之间共享UI的实验,这一步完成,后面开发应用时就方便多了(只针对UI修改)。
2. 先来体验下各端最终效果

Windows桌面、Blazor Server(在线)、Blazor Wasm(在线)、Android效果

iPad Air、iOS、macOS桌面效果

MAUI各端未做发布文件体验(需要做相应平台的发布签名等操作),大家可以按下面介绍的方法创建项目编译体验一下。
iOS和macOS效果感谢青城同学提供的图片素材,站长mbp安装了最新的macOS,xCode也是最新的,可能因为预览版macOS原因,xCode无法打开,间接影响了maui编译?
macOS版本和xCode版本

xCode为不可用状态

VS编译出错,后面再解决

用mbp的同学建议不要安装预览版操作系统,不要当勇士....
3. 新建项目

关于MAUI的环境搭建可参考这篇文章《在MAUI中使用Masa Blazor》,本文不再介绍环境搭建,直接使用VS 2022最新预览版项目模板创建项目。
3.1 创建Blazor Server项目:Dotnet9.Server


3.2 创建Blazor WebAssembly项目:Dotnet9.Wasm


3.3 创建MAUI Blazor项目:Dotnet9.MAUI


3.4 查找共同点

在3个项目的上一层目录,打开PowerShell,输入tree /f查看详细的目录文件组织结构:

仔细查看三个模板项目文件结构,我们找出共同的文件查看:
  1. 文件夹 PATH 列表
  2. 卷序列号为 76F5-AF62
  3. C:.
  4. │  Dotnet9.sln
  5. ├─Dotnet9.MAUI
  6. 【1 这里省略数个文件】
  7. │  │
  8. │  ├─Data
  9. │  │      WeatherForecast.cs
  10. │  │      WeatherForecastService.cs
  11. │  │
  12. │  ├─Pages
  13. │  │      Counter.razor
  14. │  │      FetchData.razor
  15. │  │      Index.razor
  16. 【2 这里省略数个文件】
  17. │  │
  18. │  ├─Shared
  19. │  │      MainLayout.razor
  20. │  │      MainLayout.razor.css
  21. │  │      NavMenu.razor
  22. │  │      NavMenu.razor.css
  23. │  │      SurveyPrompt.razor
  24. 【3 这里省略数个文件】
  25. ├─Dotnet9.Server
  26. │  │  App.razor
  27. 【4 这里省略数个文件】
  28. │  │
  29. │  ├─Data
  30. │  │      WeatherForecast.cs
  31. │  │      WeatherForecastService.cs
  32. │  │
  33. │  ├─Pages
  34. │  │      Counter.razor
  35. │  │      Error.cshtml
  36. │  │      Error.cshtml.cs
  37. │  │      FetchData.razor
  38. │  │      Index.razor
  39. │  │      _Host.cshtml
  40. │  │      _Layout.cshtml
  41. │  │
  42. │  ├─Properties
  43. │  │      launchSettings.json
  44. │  │
  45. │  ├─Shared
  46. │  │      MainLayout.razor
  47. │  │      MainLayout.razor.css
  48. │  │      NavMenu.razor
  49. │  │      NavMenu.razor.css
  50. │  │      SurveyPrompt.razor
  51. 【5 这里省略数个文件】
  52. └─Dotnet9.Wasm
  53. 【6 这里省略数个文件】
  54.     │
  55.     ├─Pages
  56.     │      Counter.razor
  57.     │      FetchData.razor
  58.     │      Index.razor
  59.     │
  60.     ├─Properties
  61.     │      launchSettings.json
  62.     │
  63.     ├─Shared
  64.     │      MainLayout.razor
  65.     │      MainLayout.razor.css
  66.     │      NavMenu.razor
  67.     │      NavMenu.razor.css
  68.     │      SurveyPrompt.razor
  69. 【7 这里省略数个文件】
复制代码
发现都有Data目录和Pages目录(其中Wasm项目没有Data目录,使用的示例类是直接写在FetchData.razor文件@code{}中的),那把这部分文件直接提取到类库中就可以了,那就做吧。
4. 提取UI到Razor类库

创建Razor类库:Dotnet9.WebApp

下面开始UI的提取

如上图,将Dotnet9.MAUI项目的Data、Pages、Shared三个目录外加Main.razor文件剪切到Dotnet9.WebApp项目中,然后修改剪切后相应文件的命名空间Dotnet9.MAUI[xxx]为Dotnet9.WebApp[xxx],打开Dotnet9.WebApp项目的_Import.razor文件,参考Dotnet9.MAUI项目的_Import.razor文件部分命名空间,修改如下:
  1. @using System.Net.Http
  2. @using Microsoft.AspNetCore.Authorization
  3. @using Microsoft.AspNetCore.Components.Forms
  4. @using Microsoft.AspNetCore.Components.Routing
  5. @using Microsoft.AspNetCore.Components.Web
  6. @using Microsoft.AspNetCore.Components.Web.Virtualization
  7. @using Microsoft.JSInterop
  8. @using Dotnet9.WebApp
  9. @using Dotnet9.WebApp.Shared
复制代码
上面部分命名空间可以删除(未尝试),编译Dotnet9.WebApp项目,检查是否正确编译。
5. 各端项目修改

5.1 MAUI项目


  • 添加Dotnet9.WebApp项目引用
  • Program.cs中using Dotnet9.MAUI.Data;改为using Dotnet9.WebApp.Data
  • 删除Data、Pages、Shared三个目录外加Main.razor文件,上一步是剪切的话这步省略
  • 修改_Imports.razor文件,主要是添加Dotnet9.WebApp项目命名空间引用
  1. @using System.Net.Http
  2. @using Microsoft.AspNetCore.Components.Forms
  3. @using Microsoft.AspNetCore.Components.Routing
  4. @using Microsoft.AspNetCore.Components.Web
  5. @using Microsoft.AspNetCore.Components.Web.Virtualization
  6. @using Microsoft.JSInterop
  7. @using Dotnet9.MAUI
  8. @using Dotnet9.WebApp
  9. @using Dotnet9.WebApp.Shared
复制代码

  • MauiProgram.cs修改引用的命名空间:using Dotnet9.MAUI.Data; => using Dotnet9.WebApp.Data;
  • 打开MainPage.xaml,对路由组件命名空间的引用修改
添加命名空间xmlns:webApp="clr-namespace:Dotnet9.WebApp;assembly=Dotnet9.WebApp",修改代码如下:
修改前:
  1. [/code]修改后:
  2. [code]
复制代码
修改完毕,编译运行Dotnet9.MAUI项目吧,接下来修改Dotnet9.Server项目。
5.2 Blazor Server项目


  • 添加Dotnet9.WebApp项目引用
  • Program.cs中using Dotnet9.Server.Data;改为using Dotnet9.WebApp.Data;
  • 删除Data目录
  • 删除Pages目录中的Counter.razor、FetchData.razor、Index.razor三个文件(包括同名的.cs、.css文件)
  • 删除Shared目录
  • 修改_Imports.razor文件,主要是添加Dotnet9.WebApp项目命名空间引用
  1. @using System.Net.Http
  2. @using Microsoft.AspNetCore.Authorization
  3. @using Microsoft.AspNetCore.Components.Authorization
  4. @using Microsoft.AspNetCore.Components.Forms
  5. @using Microsoft.AspNetCore.Components.Routing
  6. @using Microsoft.AspNetCore.Components.Web
  7. @using Microsoft.AspNetCore.Components.Web.Virtualization
  8. @using Microsoft.JSInterop
  9. @using Dotnet9.Server
  10. @using Dotnet9.WebApp
  11. @using Dotnet9.WebApp.Shared
复制代码

  • 打开./Pages/_Host.cshtml文件,添加命名空间引用@using Dotnet9.WebApp,修改代码如下:
修改前:
  1. [/code]修改后:
  2. [code]
复制代码
修改完毕,编译运行Dotnet9.Server项目吧,接下来修改Dotnet9.Wasm项目。
5.3 Blazor Wasm项目


  • 添加Dotnet9.WebApp项目引用
  • 删除Pages、Shared目录外加App.razor文件
  • Program.cs中using Dotnet9.Wasm;改为using Dotnet9.WebApp;,同时修改代码
修改前
  1. builder.RootComponents.Add<App>("#app");
复制代码
修改后
  1. builder.RootComponents.Add<App>("#app");
复制代码

  • 修改_Imports.razor文件,主要是添加Dotnet9.WebApp项目命名空间引用
  1. @using System.Net.Http
  2. @using Microsoft.AspNetCore.Authorization
  3. @using Microsoft.AspNetCore.Components.Authorization
  4. @using Microsoft.AspNetCore.Components.Forms
  5. @using Microsoft.AspNetCore.Components.Routing
  6. @using Microsoft.AspNetCore.Components.Web
  7. @using Microsoft.AspNetCore.Components.Web.Virtualization
  8. @using Microsoft.JSInterop
  9. @using Dotnet9.Server
  10. @using Dotnet9.WebApp
  11. @using Dotnet9.WebApp.Shared
复制代码
修改完毕,编译运行Dotnet9.Wasm项目,至此三种项目模板已经修改完成,最终解决方案如下图:

6 总结

总结就是下图:


  • Dotnet9.WebApp:blazor组件相关的代码、路由组件等放在这个工程,供其他项目引用
  • Dotnet9.Server:Blazor Server模板项目
  • Dotnet9.Wasm:Blazor WebAssembly项目
  • Dotnet9.MAUI:MAUI Blazor项目
一句话:将UI封装到Razor类库Dotnet9.WebApp,其他终端工程(Dotnet9.Server、Dotnet9.MAUI、Dotnet9.Wasm)引用此工程即可实现UI共享。
参考

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

火影

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表