MAUI與Blazor共享一套UI,媲美Flutter,實現Windows、macOS、Android、iOS、Web通用UI

1. 前言

距離上次發《MAUI初體驗:爽》一文已經過去2個月了,本計劃是下半年或者明年再研究MAUI的,現在計劃提前啦,因為我覺得MAUI Blazor挺有意思的:在Android、iOS、macOS、Windows之間共享UI,一處UI增加或者修改,就能得到一致的UI體驗。

看看這篇文章《Blazor Hybrid/MAUI 簡介和實戰[1]》對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. 先來體驗下各端最終效果

  • Blazor Server:http://server.dotnet9.com/

  • Blazor Wasm:http://wasm.dotnet9.com/

  • MAUI(Android\Windows\macOS):https://github.com/dotnet9/Dotnet9/tree/develop/src/Dotnet9.MAUI(源碼自行編譯)

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

cbaebfbb91876a681f08f22372ac0c57.gif

iOS、macOS桌面效果

12303d8f326c18bbb313ed8cecece356.png

MAUI各端未做發布文件體驗(需要做相應平臺的發布簽名等操作),大家可以按下面介紹的方法創建項目編譯體驗一下。

iOS和macOS效果感謝青城同學[2]提供的圖片素材,站長mbp安裝了最新的macOS,xCode也是最新的,可能因為預覽版macOS原因,xCode無法打開,間接影響了maui編譯?

f37d0482fec644c0d57d74c3cc118760.png

3. 新建項目

關于MAUI的環境搭建可參考這篇文章《在MAUI中使用Masa Blazor》,本文不再介紹環境搭建,直接使用VS 2022最新預覽版項目模板創建項目。

3.1 創建Blazor Server項目:Dotnet9.Server

a85a5b682b1f07445da2ff7dba4cb6d8.png

3.2 創建Blazor WebAssembly項目:Dotnet9.Wasm

a91d961c5835607a6ed9f8a1731d202b.png

3.3 創建MAUI Blazor項目:Dotnet9.MAUI

0fd4985f12ecea54296e1ede0954b35b.png

3.4 查找共同點

在3個項目的上一層目錄,打開PowerShell,輸入tree /f查看詳細的目錄文件組織結構:

d9586ef55a357ae78c121286bf0414bc.gif

仔細查看三個模板項目文件結構,我們找出共同的文件查看:

文件夾?PATH?列表
卷序列號為?76F5-AF62
C:.
│??Dotnet9.sln
│
├─Dotnet9.MAUI
【1?這里省略數個文件】
│??│
│??├─Data
│??│??????WeatherForecast.cs
│??│??????WeatherForecastService.cs
│??│
│??├─Pages
│??│??????Counter.razor
│??│??????FetchData.razor
│??│??????Index.razor
【2?這里省略數個文件】
│??│
│??├─Shared
│??│??????MainLayout.razor
│??│??????MainLayout.razor.css
│??│??????NavMenu.razor
│??│??????NavMenu.razor.css
│??│??????SurveyPrompt.razor
【3?這里省略數個文件】
│
├─Dotnet9.Server
│??│??App.razor
【4?這里省略數個文件】
│??│
│??├─Data
│??│??????WeatherForecast.cs
│??│??????WeatherForecastService.cs
│??│
│??├─Pages
│??│??????Counter.razor
│??│??????Error.cshtml
│??│??????Error.cshtml.cs
│??│??????FetchData.razor
│??│??????Index.razor
│??│??????_Host.cshtml
│??│??????_Layout.cshtml
│??│
│??├─Properties
│??│??????launchSettings.json
│??│
│??├─Shared
│??│??????MainLayout.razor
│??│??????MainLayout.razor.css
│??│??????NavMenu.razor
│??│??????NavMenu.razor.css
│??│??????SurveyPrompt.razor
【5?這里省略數個文件】
│
└─Dotnet9.Wasm
【6?這里省略數個文件】│├─Pages│??????Counter.razor│??????FetchData.razor│??????Index.razor│├─Properties│??????launchSettings.json│├─Shared│??????MainLayout.razor│??????MainLayout.razor.css│??????NavMenu.razor│??????NavMenu.razor.css│??????SurveyPrompt.razor
【7?這里省略數個文件】

發現都有Data目錄和Pages目錄(其中Wasm項目沒有Data目錄,使用的示例類是直接寫在FetchData.razor文件@code{}中的),那把這部分文件直接提取到類庫中就可以了,那就做吧。

4. 提取UI到Razor類庫

創建Razor類庫:Dotnet9.WebApp

5771f4f1ce243638a12c8503bcb6a728.png

下面開始UI的提取

5839a63dd4e748807d00b4b0b03fd145.png

如上圖,將Dotnet9.MAUI項目的DataPagesShared三個目錄外加Main.razor文件剪切到Dotnet9.WebApp項目中,然后修改剪切后相應文件的命名空間Dotnet9.MAUI[xxx]Dotnet9.WebApp[xxx],打開Dotnet9.WebApp項目的_Import.razor文件,參考Dotnet9.MAUI項目的_Import.razor文件部分命名空間,修改如下:

@using?System.Net.Http
@using?Microsoft.AspNetCore.Authorization
@using?Microsoft.AspNetCore.Components.Forms
@using?Microsoft.AspNetCore.Components.Routing
@using?Microsoft.AspNetCore.Components.Web
@using?Microsoft.AspNetCore.Components.Web.Virtualization
@using?Microsoft.JSInterop
@using?Dotnet9.WebApp
@using?Dotnet9.WebApp.Shared

上面部分命名空間可以刪除(未嘗試),編譯Dotnet9.WebApp項目,檢查是否正確編譯。

5. 各端項目修改

5.1 MAUI項目

  1. 添加Dotnet9.WebApp項目引用

  2. Program.csusing Dotnet9.MAUI.Data;改為using Dotnet9.WebApp.Data

  3. 刪除DataPagesShared三個目錄外加Main.razor文件,上一步是剪切的話這步省略

  4. 修改_Imports.razor文件,主要是添加Dotnet9.WebApp項目命名空間引用

@using?System.Net.Http
@using?Microsoft.AspNetCore.Components.Forms
@using?Microsoft.AspNetCore.Components.Routing
@using?Microsoft.AspNetCore.Components.Web
@using?Microsoft.AspNetCore.Components.Web.Virtualization
@using?Microsoft.JSInterop
@using?Dotnet9.MAUI
@using?Dotnet9.WebApp
@using?Dotnet9.WebApp.Shared
  1. MauiProgram.cs修改引用的命名空間:using Dotnet9.MAUI.Data; => using Dotnet9.WebApp.Data;

  2. 打開MainPage.xaml,對路由組件命名空間的引用修改

添加命名空間xmlns:webApp="clr-namespace:Dotnet9.WebApp;assembly=Dotnet9.WebApp",修改代碼如下:

修改前:

<RootComponent?Selector="#app"?ComponentType="{x:Type?local:Main}"?/>

修改后:

<RootComponent?Selector="#app"?ComponentType="{x:Type?webApp:Main}"?/>

修改完畢,編譯運行Dotnet9.MAUI項目吧,接下來修改Dotnet9.Server項目。

5.2 Blazor Server項目

  1. 添加Dotnet9.WebApp項目引用

  2. Program.csusing Dotnet9.Server.Data;改為using Dotnet9.WebApp.Data;

  3. 刪除Data目錄

  4. 刪除Pages目錄中的Counter.razorFetchData.razorIndex.razor三個文件(包括同名的.cs.css文件)

  5. 刪除Shared目錄

  6. 修改_Imports.razor文件,主要是添加Dotnet9.WebApp項目命名空間引用

@using?System.Net.Http
@using?Microsoft.AspNetCore.Authorization
@using?Microsoft.AspNetCore.Components.Authorization
@using?Microsoft.AspNetCore.Components.Forms
@using?Microsoft.AspNetCore.Components.Routing
@using?Microsoft.AspNetCore.Components.Web
@using?Microsoft.AspNetCore.Components.Web.Virtualization
@using?Microsoft.JSInterop
@using?Dotnet9.Server
@using?Dotnet9.WebApp
@using?Dotnet9.WebApp.Shared
  1. 打開./Pages/_Host.cshtml文件,添加命名空間引用@using Dotnet9.WebApp,修改代碼如下:

修改前:

<component?type="typeof(App)"?render-mode="ServerPrerendered"?/>

修改后:

<component?type="typeof(Main)"?render-mode="ServerPrerendered"?/>

修改完畢,編譯運行Dotnet9.Server項目吧,接下來修改Dotnet9.Wasm項目。

5.3 Blazor Wasm項目

  1. 添加Dotnet9.WebApp項目引用

  2. 刪除PagesShared目錄外加App.razor文件

  3. Program.csusing Dotnet9.Wasm;改為using Dotnet9.WebApp;,同時修改代碼

修改前

builder.RootComponents.Add<App>("#app");

修改后

builder.RootComponents.Add<Main>("#app");
  1. 修改_Imports.razor文件,主要是添加Dotnet9.WebApp項目命名空間引用

@using?System.Net.Http
@using?Microsoft.AspNetCore.Authorization
@using?Microsoft.AspNetCore.Components.Authorization
@using?Microsoft.AspNetCore.Components.Forms
@using?Microsoft.AspNetCore.Components.Routing
@using?Microsoft.AspNetCore.Components.Web
@using?Microsoft.AspNetCore.Components.Web.Virtualization
@using?Microsoft.JSInterop
@using?Dotnet9.Server
@using?Dotnet9.WebApp
@using?Dotnet9.WebApp.Shared

修改完畢,編譯運行Dotnet9.Wasm項目,至此三種項目模板已經修改完成,最終解決方案如下圖:

f229cb995649e05c6bc3e12f1f367f94.png

6 總結

總結就是下圖:

7cfb94053f52bb951d61a5d67b5554f7.png
  • Dotnet9.WebApp:blazor組件相關的代碼、路由組件等放在這個工程,供其他項目引用

  • Dotnet9.Server:Blazor Server模板項目

  • Dotnet9.Wasm:Blazor WebAssembly項目

  • Dotnet9.MAUI:MAUI Blazor項目

一句話:將UI封裝到Razor類庫Dotnet9.WebApp,其他終端工程(Dotnet9.ServerDotnet9.MAUIDotnet9.Wasm)引用此工程即可實現UI共享。

  • 本文代碼地址:https://github.com/dotnet9/Dotnet9[3]

  • 原文:https://dotnet9.com/2022/06/Share-razor-library-between-maui-and-blazor-server-or-client[4]

參考

  1. ASP.NET Community Standup - Native client apps with Blazor Hybrid[5]

  2. Blazor一份代碼在Blazor WebAssembly和Blazor Server之間任意切換[6]

  3. 微軟MAUI文檔[7]

  4. 微軟Blazor文檔[8]

  5. 學Blazor[9]

參考資料

[1]

Blazor Hybrid/MAUI 簡介和實戰: https://www.cnblogs.com/densen2014/p/16240966.html

[2]

青城同學: https://iwscl.com/

[3]

https://github.com/dotnet9/Dotnet9: https://github.com/dotnet9/Dotnet9

[4]

https://dotnet9.com/2022/06/Share-razor-library-between-maui-and-blazor-server-or-client: https://dotnet9.com/2022/06/Share-razor-library-between-maui-and-blazor-server-or-client

[5]

ASP.NET Community Standup - Native client apps with Blazor Hybrid: https://www.youtube.com/watch?v=7UM6s0QPvRQ

[6]

Blazor一份代碼在Blazor WebAssembly和Blazor Server之間任意切換: https://www.bilibili.com/video/BV1ty4y137yA?spm_id_from=333.337.search-card.all.click&vd_source=fc9bd0ca1f113a165ad3ebf4fb79b124

[7]

微軟MAUI文檔: https://docs.microsoft.com/zh-cn/dotnet/maui/?WT.mc_id=dotnet-35129-website

[8]

微軟Blazor文檔: https://docs.microsoft.com/zh-cn/aspnet/core/blazor/?WT.mc_id=dotnet-35129-website&view=aspnetcore-6.0

[9]

學Blazor: https://dotnet9.com/album/Let-us-learn-blazor-together

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/285734.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/285734.shtml
英文地址,請注明出處:http://en.pswp.cn/news/285734.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

dns 報文格式

最近學習了下DNS的格式&#xff0c;發現很多內容都是轉載自同一個而且說的不是很清楚&#xff0c;特再整理下具體可以查看RFC1035 http://www.ietf.org/rfc/rfc1035.txt有詳細的解釋對于英語理解不是很好和懶得看這么長的可以看下本文首先是DNS數據幀的格式-------------------…

input file實現批量上傳

1、需求實現word批量上傳。 2、使用插件jquery-form.js 3、html代碼 注意 multiple"multiple" 1 <form id"frm_upload" method"post" enctype"multipart/form-data"> 2   <input type"file" id"filepath&qu…

【Pix4d精品教程】Pix4d修編正射影像DOM的兩種方法案例詳解

《無人機航空攝影測量精品教程》合集目錄(Pix4d、CC、EPS、PhotoScan、Inpho) DOM修編前: DOM修編后: 文章摘要: Pix4d內業數據處理通常會生成點云、DSM和DOM等產品,DSM經過精編可以生成精準的DEM,而DOM一般情況下,存在比如房屋邊緣被拉花,或者存在噪點的情況

刪除Linux下/tmp目錄引起的不正常登錄系統

現象&#xff1a;/tmp占用400M的空間(里面全部是亂七八糟的東西) 動作&#xff1a;刪除/tmp目錄 后果&#xff1a;造成只能啟動到控制臺模式 應急&#xff1a; 1 創建目錄&#xff1a;#mkdir /tmp 結果系統在控制臺模式登錄和X windows模式登錄狀態間反復切換&#xff0c;不能進…

C語言試題八十五之狼追兔子問題

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 一只兔子躲…

[轉]快速使用FileProvider解決Android7.0文件權限問題

升級到Android7.0之后&#xff0c;啟動系統相機或者截圖&#xff0c;傳入URI的時候可能會導致程序閃退崩潰。這是因為7.0的新的文件權限導致的。下面是解決這個問題的快速解決方案。 問題代碼 在7.0可能會出問題的代碼&#xff1a; final String CACHE_IMG Environment.getExt…

終于找到了,開源的Vue3+.NET6通用管理后臺!

據說80%的.NET項目都是管理后臺&#xff0c;然而能用上Vue3.NET6的管理后臺并不多見。這里分享一套Vue3 Axios TS Vite ElementUI Plus .NET 6 WebAPI JWT SqlSugar的前后端分離架構的通用管理后臺源碼數據庫腳本&#xff0c;還有與之配套錄制的一組視頻教程&#xff0c;全部打…

【Pix4d精品教程】Pix4d模型成果導出OSGB并加載OSGB到EPS進行三維測圖完美案例教程

《無人機航空攝影測量精品教程》合集目錄(Pix4d、CC、EPS、PhotoScan、Inpho) 在垂直攝影中,Pix4d也可以生成漂亮的三維模型,并導出為OSGB,加載到EPS進行三維測圖。首先來看生成的三維格網紋理和EPS三維模型加載效果。 Pix4d生成的三維格網紋理: EPS加載OSGB模型效果: 文…

Vim 批量替換

假設在非Win系統下。 想批量替換文本不再是Ctrl&#xff0b;F那么簡單了&#xff0c; 一般用Vim來做批量替換&#xff0c; 略微復雜點&#xff1a; 比如將192.168.0.1替換為192.168.0.2 :%s/192.168.0.1/192.168.0.2/g

Android實現ListView(1)

昨天有個朋友問我Android ListView列表視圖&#xff0c;遇到了點錯誤&#xff0c;今天我給大家演示&#xff0c;具體實現見圖&#xff1a; 1&#xff1a;創建一個item布局layout/item.xml 2&#xff1a;創建一個ListViewActivity類&#xff0c;但是必須繼承ListActivity&#x…

WolframAlpha 的使用

WolframAlpha 1. 求解復雜方程組 ab?4abc2ac1直接點開網站&#xff0c;在輸入框中輸入&#xff0c;ab-4;abc2;ac1;&#xff08;逗號分割開來&#xff09;&#xff0c; 轉載于:https://www.cnblogs.com/mtcnn/p/9423087.html

C語言試題八十六之兔子生兔子問題

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 假設一對兔…

聊聊 C# 中的 Composite 模式

?寫在前面 Composite組合模式屬于設計模式中比較熱門的一個&#xff0c;相信大家對它一定不像對訪問者模式那么陌生&#xff0c;畢竟誰又沒有遇到過樹形結構呢。不過所謂溫故而知新&#xff0c;我們還是從一個例子出發&#xff0c;起底一下這個模式吧。一個簡單例子 設想我們…

140種Python標準庫、第三方庫和外部工具都有了

導讀&#xff1a;Python數據工具箱涵蓋從數據源到數據可視化的完整流程中涉及到的常用庫、函數和外部工具。其中既有Python內置函數和標準庫&#xff0c;又有第三方庫和工具。 這些庫可用于文件讀寫、網絡抓取和解析、數據連接、數清洗轉換、數據計算和統計分析、圖像和視頻處理…

【CC精品教程】任務一:CC新建工程、添加照片、相機參數設置、選擇坐標系統

《無人機航空攝影測量精品教程》合集目錄(Pix4d、CC、EPS、PhotoScan、Inpho) 同Pix4d一樣,CC(Context Capture),也稱Smart 3D,也是無人機航測中人手必備的一款軟件,在空三運算,三維模型構建等傾斜攝影測量方面有很大的優勢,精度也相當高。本CC系列精品教程從項目的角…

C語言試題八十七之實現選擇排序算法

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 C語言選擇排…

java concurrent之前戲synchronized

對于多線程共享資源的情況須要進行同步&#xff0c;以避免一個線程的修改被還有一個線程的修改所覆蓋。最普遍的同步方式就是synchronized。把代碼聲明為synchronized。有兩個重要后果&#xff0c;一般是指該代碼具有 原子性&#xff08;atomicity&#xff09;和 可見性&#x…

開源項目【zheng】搭建流程

2019獨角獸企業重金招聘Python工程師標準>>> 搭建過程 項目地址 https://gitee.com/shuzheng/zheng這兩篇寫的比較詳細的搭建過程&#xff0c;結合一下就沒什么問題了。 https://my.oschina.net/yzuzhang/blog/1538555http://www.jianshu.com/p/b2fb42e17b581.JDK 1…

簡述HTML DOM及其節點分類

在JavaScript中&#xff0c;document這個對象大家一定很熟悉&#xff0c;哪怕是剛剛開始學習的新人&#xff0c;也會很快接觸到這個對象。而document對象不僅僅是一個普通的JavaScript內置對象&#xff0c;它還是一個巨大API的核心對象&#xff0c;這個巨大的API就是DOM&#x…

【CC精品教程】任務二:導入像控點、差分POS,空三平差權重設置,提交自由空三

《無人機航空攝影測量精品教程》合集目錄(Pix4d、CC、EPS、PhotoScan、Inpho) 【CC精品教程】任務一:CC新建工程、添加照片、相機參數設置、選擇坐標系統 本任務接著上一個任務,繼續完成CC項目作業,主要內容有:導入像控點、選擇空間參考系統,導入差分POS,空三平差權重設…