NET MAUIでVueを使用したハイブリッド開発

NET MAUIでVueを使用したハイブリッド開発

MAUIでのマイクロソフトの公式な計画はBlazorで開発することですが、現在市場に出回っているほとんどのWebプロジェクトはVueやReactなどのテクノロジーを使用しており、蓄積されたテクノロジーをバイパスできなければ、プロジェクト全体をBlazorで書き直すことは現実的ではありません。

最后更新 2022/01/18 22:11
林 小
预计阅读 8 分钟
分类
MAUI
标签
.NET C# Blazor MAUI Vue

MAUIでのマイクロソフトの公式な計画はBlazorで開発することですが、現在市場に出回っているほとんどのWebプロジェクトはVueやReactなどのテクノロジーを使用しており、蓄積されたテクノロジーをバイパスできなければ、プロジェクト全体をBlazorで書き直すことは現実的ではありません。

Vueは現在人気のあるWebフレームワークであり、単純に言えば、WebページのMVVMモード開発を実現するために“テンプレート”と“バインディング”の2つの機能を使用するテンプレートエンジンです。. NET MAUIフレームワークを使用して、VueアプリケーションをWebコンテナに埋め込むことができます。クロスプラットフォームのハイブリッド開発が可能です。

例えば、ヘルスケア業界のプロジェクトでは、このハイブリッド開発アプローチを使用してアプリケーションを構築しました。Vueコードはほとんど変更せず、クロスプラットフォームで実行できます。

Vueで開発されたウェブサイトのセットがある場合は、この記事を参考に、iPhone、Android、タブレットなどのモバイルデバイスに値を移行してみてください。

ハイブリッド開発の中核は、Webと. NETの相互運用性を構築することであり、Blazorエンジンの以下の機能を活用します。

  • 資源の統一管理
  • Jsコードの注入
  • C#コードを呼び出す。
  • C#はJSコードを呼び出す

如果你还不了解混合开发的概念,请回看上一章节[MAUI] 混合开发概念_jevonsflash 的专栏-CSDN 博客

全体の作業は、MAUIセクション、Vueセクション、および混合改造に分かれています。

MAUIのセクション

Maui Appプロジェクトを作成する

MatoProjectという名前のMaui Blazor Appプロジェクトを作成することもできますが、このテンプレートはBlazorを中心に開発されており、不要な機能もあり、多くのファイルを削除する必要があります。

作成後にMatoProject.csprojを編集し、Sdkの最後に.Razorを追加すると、VSはMicrosoft.AspNetCore.Components.WebView.Maui依存パッケージを自動的にインストールします(NuGetでこのパッケージを手動で追加しないでください。

インストール完了後、プロジェクトディレクトリにw w wrootフォルダを作成します。

このフォルダはハイブリッド開発のWebセクションのルートになります。名前は簡単に定義できません。

Microsoft.AspNetCore.Components.WebView. Maui.targetsファイルを開きます。

我们可以看到构建项目时,这个库会将 wwwroot 文件夹里的内容作为 Maui 资源(MauiAsset)类型设置标签,编译器则会根据 MauiAsset 标签将这些内容打包进各个平台的资源文件夹,具体的 Maui 资源类型可以参考这个文章.NET MAUI – Manage App Resources – Developer Thoughts (egvijayanand.in)

MauiProgram.csを開き、BlazorMauiWebViewコンポーネントをbuilderに登録し、サービスに拡張メソッドAddBlazorWebViewを使用してBlazorに関連するサービスを追加します。

using Microsoft.Maui;
using Microsoft.Maui.Hosting;
using Microsoft.Maui.Controls.Compatibility;
using Microsoft.Maui.Controls.Hosting;
using Microsoft.AspNetCore.Components.WebView.Maui;
using Microsoft.Extensions.DependencyInjection;

namespace MatoProject
{
	public static class MauiProgram
	{
		public static MauiApp CreateMauiApp()
		{
			var builder = MauiApp.CreateBuilder();
			builder
				.RegisterBlazorMauiWebView()
				.UseMauiApp<App>()
				.ConfigureFonts(fonts =>
				{
					fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
				});
			builder.Services.AddBlazorWebView();
			return builder.Build();
		}
	}
}

MainPage.xamlを開き、ネイティブアプリのメインページを編集します。

Blazor WebViewコントロールを画面に設定し、HostPageをWebセクションのホームページに設定します。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MatoProject.MainPage"
             xmlns:b="clr-namespace:Microsoft.AspNetCore.Components.WebView.Maui;assembly=Microsoft.AspNetCore.Components.WebView.Maui"
             BackgroundColor="{DynamicResource SecondaryColor}">

    <Grid>
        <b:BlazorWebView HostPage="wwwroot/index.html">
            <b:BlazorWebView.RootComponents>
                <b:RootComponent Selector="#blazorapp" x:Name="MainWebView" ComponentType="{x:Type local:Index}/>
            </b:BlazorWebView.RootComponents>
        </b:BlazorWebView>
    </Grid>
</ContentPage>

_import.razorを作成する

@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 MatoProject

セクション

ネイティブ開発のWebコンテナをセットアップしたので、Vueプロジェクトに取り組む必要があります。

プロジェクトディレクトリにcdし、vue-cliを使用して空のVueプロジェクトを作成します。

2.0プロジェクトを選択し、Typescript、ES 6のクラス命名方法などをサポートし、最終的にはwebpack経由で静的リソースとしてパッケージ化されるので、問題ではありません。

src/api/fooService.tsを作成し、以下の関数を作成します。

window['DotNet']オブジェクトはMAUI Blazorに注入されたインタラクティブオブジェクトになります。

export async function GetAll(data) {
  var result = null;
  await window["DotNet"]
    .invokeMethodAsync("MatoProject", "GetFoo")
    .then((data) => {
      console.log("DotNet method return the value:" + data);
      result = data;
    });
  return result;
}

export async function Add(data) {
  var result = null;
  await window["DotNet"]
    .invokeMethodAsync("MatoProject", "Add", data)
    .then((data) => {
      console.log("DotNet method return the value:" + data);
      result = data;
    });
  return result;
}

Home.vue編集を開きます。

これはウェブのメインページで、C#との相互作用をテストするために3つのボタンと関連する関数が必要です。

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <div>
      <h3>foo:</h3>
      <button @click="getFoo">click to get foo</button>
      <br />
      <span>{{ foo }}</span>
    </div>
    <div>
      <h3>bar:</h3>
      <span>{{ bar }}</span>
    </div>
    <div>
      <button @click="add">click here to add</button>
      <span>click count:{{ cnt }}</span>
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import HelloWorld from "@/components/HelloWorld.vue"; // @ is an alias to /src
import { GetAll, Add } from "@/api/fooService";

@Component({
  components: {
    HelloWorld,
  },
})
export default class Home extends Vue {
  foo: string = "";
  bar: string = "";
  cnt: number = 0;

  async created() {
    window["postBar"] = this.postBar;
  }
  async add() {
    this.cnt = await Add({ a: this.cnt, b: 1 });
  }

  async getFoo() {
    var foo = await GetAll(null);
    this.foo = foo;
  }

  async postBar(data) {
    this.bar = data;
    console.log("DotNet invocked the function with param:" + data);
    return this.bar;
  }
}
</script>

これで簡単なVueプロジェクトが完了しました。

パッケージングコマンドを実行する:

PS D:\Project\maui-vue-hybirddev\hybird-host> yarn build

distディレクトリ内のすべてのコンテンツをw w wrootフォルダの下にコピーします。

混合変換の変更

これは、MAUIプロジェクトをVueに適合させるハイブリッド開発の焦点です。

w w wroot/index.jsを開きます:

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="icon" href="favicon.ico" />
    <title>hybird-host</title>
    <link href="js/about.dc8b0f2b.js" rel="prefetch" />
    <link href="css/app.03043124.css" rel="preload" as="style" />
    <link
      href="js/app.b6b5425b.js"
      rel="preload"
      as="script"
      crossorigin="anonymous"
    />
    <link
      href="js/chunk-vendors.cf6d8f84.js"
      rel="preload"
      as="script"
      crossorigin="anonymous"
    />
    <link href="css/app.03043124.css" rel="stylesheet" />
  </head>
  <body>
    <div id="blazorapp">Loading...</div>
    <script src="_framework/blazor.webview.js" autostart="false"></script>
  </body>
</html>

** body 部分のみを書き換え、headのリンクラベルの内容を変更せず、クロスドメインの問題を解決するためにjsの後にcrossorigin=“anonymous”を追加します。**

Inde x.razorファイルの作成:

@using Microsoft.Maui.Controls @inject IJSRuntime JSRuntime @implements
IDisposable
<noscript
  ><strong
    >We're sorry but CareAtHome doesn't work properly without JavaScript
    enabled. Please enable it to continue.</strong
  ></noscript
>
<div id="app"></div>
@code { [JSInvokable] public static Task<string>
  GetFoo() { return Task.FromResult("this is foo call C# method from js"); }
  [JSInvokable] public static Task<int>
    Add(AddInput addInput) { return Task.FromResult(addInput.a + addInput.b); }
    public async void Post(object o, EventArgs a) { await
    JSRuntime.InvokeAsync<string
      >("postBar", "this is bar call js method from C#"); } protected override
      async Task OnAfterRenderAsync(bool firstRender) { ((App.Current as
      App).MainPage as MainPage).OnPostBar += this.Post; try { if (firstRender)
      { await JSRuntime.InvokeAsync<IJSObjectReference
        >("import", "./js/chunk-vendors.cf6d8f84.js", new { crossorigin =
        "anonymous" }); await JSRuntime.InvokeAsync<IJSObjectReference
          >("import", "./js/app.b6b5425b.js", new { crossorigin = "anonymous"
          }); } } catch (Exception ex) { Console.WriteLine(ex); } } public void
          Dispose() { (Application.Current.MainPage as MainPage).OnPostBar -=
          this.Post; } }</IJSObjectReference
        ></IJSObjectReference
      ></string
    ></int
  ></string
>

以下の2つの文は、パッケージ化によって生成された実際のファイル名に対応し、クロスドメインラベルを付ける必要があります。

await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/chunk-vendors.cf6d8f84.js", new { crossorigin = "anonymous" });
await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/app.b6b5425b.js", new { crossorigin = "anonymous" });

MainPage.xamlボタンを作成し、イベントをトリガーするメソッドを設定します。

<button
  Text="Post Bar To WebView"
  HorizontalOptions="Center"
  VerticalOptions="End"
  HeightRequest="40"
  Clicked="PostBar_Clicked"
></button>

CodeBehind:

using System;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Essentials;

namespace MatoProject
{
	public partial class MainPage : ContentPage
	{
        public event EventHandler<EventArgs> OnPostBar;

		int count = 0;

		public MainPage()
		{
			InitializeComponent();
		}

		private async void PostBar_Clicked(object sender, EventArgs args)
		{
			OnPostBar?.Invoke(this, args);
		}
	}
}

これですべてのコード作業が完了し、PC 上でWindowsまたはAndroidエミュレータを選択してプログラムを実行できます。

操作の効果:

Windowsプラットフォーム上で動作する場合、ネイティブコントロールはEdge WebView2レンダラーを使用してページを読み込み、f 12を押すとネイティブデバッグツールが呼び出されます。

なぜこのようなテクノロジーを使うのかと思う人もいるでしょう。Ionic、React Native、Uni-appといったハイブリッド開発技術があるかもしれません。これらのテクニックにはそれぞれの利点がありますが、成熟したXamarinフレームワークがあれば、MAUIに簡単に移行したり、データ永続化のためにEFCoreを使用したり、Abpフレームワークを統合して依存注入、グローバルイベント、ローカリゼーションなどのモバイル開発で一般的な機能を設定したりできます(別の記事では、AbpをMAUIに移動する方法を説明します)。Xamarinはデバイス抽象化レイヤであり、H 5互換性の高いWebViewも提供している。

もちろん、主な理由は迅速な開発であり、コードの蓄積は貴重であり、コードの変更量が少ないことが王様です。ReactテクノロジースタックでWebコードを書いている場合は、React Nativeが最良の選択肢かもしれません。最良の技術はない、あなたに最適な技術だけがある。

** コードベース:**

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2023/01/12

Maui Blazorはカメラを使用して

Maui BlazorのインターフェイスはWebViewでレンダリングされるため、ネイティブカメラはインターフェイスコンポーネントをバインドする必要があるため、Androidカメラを使用するとアクセスできません。

继续阅读
同分类 / 同标签 2022/04/26

MAUIでのMasa Blazorの使用

`. NET MAUI`を使用すると、`Android`、`iOS`、`macOS`と`Windows`、Linuxコミュニティサポートで単一の共有コードベースから実行できるアプリケーションを開発でき、コードセットは複数で実行できる。

继续阅读
同分类 / 同标签 2024/04/11

NET MAUIオープンソースUIツールキット-Uranium

私は. NET MAUI関連のUIフレームワークを共有するためにWeChatパブリックアカウントのバックグラウンドメッセージに小さなパートナーを持っていました。今日、Dayaoは. NET MAUIオープンソース、無料のUIツールキットを共有しました。

继续阅读