MAUI與Blazor共享一套UI见咒,媲美Flutter偿衰,實現(xiàn)Windows、macOS论颅、Android哎垦、iOS、Web通用UI

1. 前言

距離上次發(fā)《MAUI初體驗:爽》一文已經(jīng)過去2個月了恃疯,本計劃是下半年或者明年再研究MAUI的漏设,現(xiàn)在計劃提前啦,因為我覺得MAUI Blazor挺有意思的:在Android今妄、iOS郑口、macOS、Windows之間共享UI盾鳞,一處UI增加或者修改犬性,就能得到一致的UI體驗。

看看這篇文章《Blazor Hybrid/MAUI 簡介和實戰(zhàn)》對MAUI Blazor的說明:

MAUI

.NET 多平臺應(yīng)用程序 UI (.NET MAUI) 是一個跨平臺框架腾仅,用于使用 C# 和 XAML 創(chuàng)建本機移動和桌面應(yīng)用程序乒裆, 使用 .net MAUI,可以開發(fā)可在 Android推励、iOS鹤耍、macOS 上運行的應(yīng)用肉迫,Windows 以及從單個共享代碼庫運行的應(yīng)用。

Blazor Hybrid 應(yīng)用和 .NET MAUI

Blazor Hybrid 支持內(nèi)置于 .NET 多平臺應(yīng)用 UI (.NET MAUI) 框架稿黄。 .NET MAUI 包含 BlazorWebView 控件喊衫,該控件運行將 Razor 組件呈現(xiàn)到嵌入式 Web View 中。 通過結(jié)合使用 .NET MAUI 和 Blazor杆怕,可以跨移動設(shè)備族购、桌面設(shè)備和 Web 重復(fù)使用一組 Web UI 組件。

今天就分享如何在Blazor Server陵珍、Blazor Wasm寝杖、MAUI Blazor之間共享UI的實驗,這一步完成互纯,后面開發(fā)應(yīng)用時就方便多了(只針對UI修改)朝墩。

2. 先來體驗下各端最終效果

Windows桌面、Blazor Server(在線)伟姐、Blazor Wasm(在線)收苏、Android效果

1301.gif

iPad Air、iOS愤兵、macOS桌面效果

1309.png

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

iOS和macOS效果感謝青城同學(xué)提供的圖片素材秆乳,站長mbp安裝了最新的macOS懦鼠,xCode也是最新的,可能因為預(yù)覽版macOS原因屹堰,xCode無法打開肛冶,間接影響了maui編譯?

macOS版本和xCode版本

1306.png

xCode為不可用狀態(tài)

1312.jpg

VS編譯出錯扯键,后面再解決

1313.jpg

用mbp的同學(xué)建議不要安裝預(yù)覽版操作系統(tǒng)睦袖,不要當勇士....

3. 新建項目

關(guān)于MAUI的環(huán)境搭建可參考這篇文章《在MAUI中使用Masa Blazor》,本文不再介紹環(huán)境搭建荣刑,直接使用VS 2022最新預(yù)覽版項目模板創(chuàng)建項目馅笙。

3.1 創(chuàng)建Blazor Server項目:Dotnet9.Server

1302.png

3.2 創(chuàng)建Blazor WebAssembly項目:Dotnet9.Wasm

1303.png

3.3 創(chuàng)建MAUI Blazor項目:Dotnet9.MAUI

1304.png

3.4 查找共同點

在3個項目的上一層目錄,打開PowerShell厉亏,輸入tree /f查看詳細的目錄文件組織結(jié)構(gòu):

1305.gif

仔細查看三個模板項目文件結(jié)構(gòu)董习,我們找出共同的文件查看:

文件夾 PATH 列表
卷序列號為 76F5-AF62
C:.
│  Dotnet9.sln
│
├─Dotnet9.MAUI
【1 這里省略數(shù)個文件】
│  │
│  ├─Data
│  │      WeatherForecast.cs
│  │      WeatherForecastService.cs
│  │
│  ├─Pages
│  │      Counter.razor
│  │      FetchData.razor
│  │      Index.razor
【2 這里省略數(shù)個文件】
│  │
│  ├─Shared
│  │      MainLayout.razor
│  │      MainLayout.razor.css
│  │      NavMenu.razor
│  │      NavMenu.razor.css
│  │      SurveyPrompt.razor
【3 這里省略數(shù)個文件】
│
├─Dotnet9.Server
│  │  App.razor
【4 這里省略數(shù)個文件】
│  │
│  ├─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 這里省略數(shù)個文件】
│
└─Dotnet9.Wasm
【6 這里省略數(shù)個文件】
    │
    ├─Pages
    │      Counter.razor
    │      FetchData.razor
    │      Index.razor
    │
    ├─Properties
    │      launchSettings.json
    │
    ├─Shared
    │      MainLayout.razor
    │      MainLayout.razor.css
    │      NavMenu.razor
    │      NavMenu.razor.css
    │      SurveyPrompt.razor
【7 這里省略數(shù)個文件】

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

4. 提取UI到Razor類庫

創(chuàng)建Razor類庫:Dotnet9.WebApp

1307.png

下面開始UI的提取

1308.png

如上圖,將Dotnet9.MAUI項目的Data窝趣、Pages蔗喂、Shared三個目錄外加Main.razor文件剪切到Dotnet9.WebApp項目中,然后修改剪切后相應(yīng)文件的命名空間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. 刪除Data预麸、PagesShared三個目錄外加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.razor砰逻、FetchData.razor鸣驱、Index.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項目鉴逞,至此三種項目模板已經(jīng)修改完成遗菠,最終解決方案如下圖:

1311.png

6 總結(jié)

總結(jié)就是下圖:

1310.png
  • Dotnet9.WebApp:blazor組件相關(guān)的代碼、路由組件等放在這個工程华蜒,供其他項目引用
  • Dotnet9.Server:Blazor Server模板項目
  • Dotnet9.Wasm:Blazor WebAssembly項目
  • Dotnet9.MAUI:MAUI Blazor項目

一句話:將UI封裝到Razor類庫Dotnet9.WebApp辙纬,其他終端工程(Dotnet9.ServerDotnet9.MAUI叭喜、Dotnet9.Wasm)引用此工程即可實現(xiàn)UI共享贺拣。

參考

  1. ASP.NET Community Standup - Native client apps with Blazor Hybrid
  2. Blazor一份代碼在Blazor WebAssembly和Blazor Server之間任意切換
  3. 微軟MAUI文檔
  4. 微軟Blazor文檔
  5. 學(xué)Blazor
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子譬涡,更是在濱河造成了極大的恐慌闪幽,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涡匀,死亡現(xiàn)場離奇詭異盯腌,居然都是意外死亡,警方通過查閱死者的電腦和手機陨瘩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門腕够,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舌劳,你說我怎么就攤上這事帚湘。” “怎么了甚淡?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵大诸,是天一觀的道長。 經(jīng)常有香客問我贯卦,道長资柔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任撵割,我火速辦了婚禮建邓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘睁枕。我一直安慰自己官边,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布外遇。 她就那樣靜靜地躺著注簿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跳仿。 梳的紋絲不亂的頭發(fā)上诡渴,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音菲语,去河邊找鬼妄辩。 笑死,一個胖子當著我的面吹牛山上,可吹牛的內(nèi)容都是我干的眼耀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼佩憾,長吁一口氣:“原來是場噩夢啊……” “哼哮伟!你這毒婦竟也來了干花?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤楞黄,失蹤者是張志新(化名)和其女友劉穎池凄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片任斋。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤眷篇,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布萎河,位于F島的核電站,受9級特大地震影響蕉饼,放射性物質(zhì)發(fā)生泄漏虐杯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一昧港、第九天 我趴在偏房一處隱蔽的房頂上張望擎椰。 院中可真熱鬧,春花似錦创肥、人聲如沸达舒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巩搏。三九已至,卻和暖如春趾代,著一層夾襖步出監(jiān)牢的瞬間贯底,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工撒强, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留禽捆,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓飘哨,卻偏偏與公主長得像胚想,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子芽隆,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容