.NET MAUI 中结合 Vue 实现混合开发
前言
在MAUI微软的官方方案是使用Blazor开发,但是当前市场大多数的Web项目使用Vue,React等技术构建,如果我们没法绕过已经积累的技术,用Blazor重写整个项目并不现实。
Vue是当前流行的web框架, 简单来说是一套模板引擎,利用“模板”和“绑定”两大特性实现web页面mvvm模式开发。利用.NET MAUI框架可以将Vue应用嵌入到Web容器中。可以实现跨平台的混合开发。
例如我在某医疗行业项目中,已经用这个混合开发的方式生成应用,Vue代码不需要做什么改动,就能跨平台运行:
如果你有一套Vue开发的网站,可以根据这篇文章,尝试移值进你的iPhone,Android以及平板电脑等移动设备。
混合开发的核心工作是构建Web与.net 的互操作,我们将利用Blazor引擎的如下功能:
资源的统一管理 js代码的注入 js调用C#代码 C#调用js代码
整个工作分为MAUI部分,Vue部分和混合改造。
MAUI部分
创建Maui App项目:
你也可以创建 Maui Blazor App 项目,命名为MatoProject,但是这个模板主要围绕Blazor开发,有的功能我们并不需要,得删很多文件。
创建完成后编辑MatoProject.csproj,在Sdk最末尾加上.Razor,VS会自动安装Microsoft.AspNetCore.Components.WebView.Maui依赖包(注意不要手动Nuget添加这个包,否则程序无法运行)
安装完成后在项目目录中创建一个wwwroot文件夹
这个文件夹将是混合开发Web部分的根目录,这个名称不能随便定义,我们看看为什么:
打开Microsoft.AspNetCore.Components.WebView.Maui.targets这个文件:
我们可以看到构建项目时,这个库会将wwwroot文件夹里的内容作为Maui资源(MauiAsset)类型设置标签,编译器则会根据MauiAsset标签将这些内容打包进各个平台的资源文件夹,具体的Maui资源类型可以参考这个文章.NET MAUI – Manage App Resources – Developer Thoughts (egvijayanand.in) ,
打开MauiProgram.cs 在builder 中注册BlazorMauiWebView组件,在服务中使用扩展方法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()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
builder.Services.AddBlazorWebView();
return builder.Build();
}
}
}
打开MainPage.xaml,编辑原生应用的主页面:
建立BlazorWebView控件铺满屏幕,并设置HostPage为Web部分的主页index.html
<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}/>
建立_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
Vue部分
至此我们建立好了原生开发的Web容器,接下来需要处理Vue项目了:
cd到项目目录,使用vue-cli创建一个空白Vue项目:
这里可以按照Vue的编程喜好建立,比如我选择了2.0项目,支持Typescript,es6的class命名方式等,最终都要通过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 编辑:
这是Web的主页面,我们需要三个按钮以及相关函数,测试js与C#的交互操作。
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
<div>
<h3>foo:h3>
<button @click="getFoo">click to get foobutton>
<br />
<span>{{ foo }}span>
div>
<div>
<h3>bar:h3>
<span>{{ bar }}span>
div>
<div>
<button @click="add">click here to addbutton>
<span>click count:{{ cnt }}span>
div>
div>
template>