dotnet9 MAUI + Vue 项目
MAUI是dotnet的跨平台技术,支持windows平台、android平台、ios平台等。使用MAUI作为基础平台,在其上运行一个前端项目,比如Vue,可以同时享受开发效率与跨平台的好处。使用dotnet9后MAUI提供的组件HybridWebView,可以实现将前端项目嵌入到MAUI项目Page中的效果。支持C#与javascript的互操作。
新建MAUI项目
- 使用dotnet9
- 在MainPage.xaml中使用HybridWebView
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage">
<ScrollView>
<HybridWebView x:Name="hybridWebView"/>
</ScrollView>
</ContentPage>
- 在MainPage.xaml.cs中,增加代码
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
hybridWebView.SetInvokeJavaScriptTarget(this);
}
}
- 为了Debug,再在MauiProgram.cs中增加代码
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
// ......
#if DEBUG
builder.Services.AddHybridWebViewDeveloperTools();
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
完成了以上准备后,就可以将前端编译好的文件,放在Resouces/Raw/wwwroot/下面了
前端项目
前端项目build默认输出到dist文件,为了方便开发部署,可以在vite.config.js中修改outDir,使其直接编译到MAUI项目的Resouces/Raw/wwwroot/文件夹中
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
const dest = "MAUI项目绝对或相对目录/Resources/Raw/wwwroot";
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
],
build: {
outDir: dest,
emptyOutDir: true,
},
});
MAUI与Vue交互
这样一个场景:MAUI作为后端,提供一个PersonService,其中维护一个List<Person>数据列表;前端Vue要获取、增加这个列表的数据。
- 编写PersonService.cs
public class PersonService
{
private readonly List<Person> persons = new();
private int maxId { get { return persons.Count; } set { value = persons.Count; } }
public void Add(string name) // 增加Person接口
{
persons.Add(new(maxId + 1, name));
}
public List<Person> GetAll(int limit = 0) // 获取所有Person接口
{
if (limit == 0) return persons;
else return persons.Take(Math.Abs(limit)).ToList();
}
}
- 让PersonService能被作为依赖注入,修改MauiProgramm.cs,增加
builder.Services.AddScoped<PersonService>();
- 在MainPage.cs中注入PersonService,并编写用来响应前端的方法
public partial class MainPage : ContentPage
{
private readonly PersonService _personService;
public MainPage(PersonService personService)
{
InitializeComponent();
_personService = personService;
hybridWebView.SetInvokeJavaScriptTarget(this);
}
public List<Person> GetAllPersons()
{
return _personService.GetAll();
}
public void AddPerson(string name)
{
_personService.Add(name);
}
}
- 接下来修改前端
前端javascript代码调用MAUI后端方法,需要使用一个脚本HybridWebView.js
在微软示例中,这个脚本是直接用src标签在index.html中引用的,但是我们使用了vue工程,因此需要模块化这个脚本。将脚本最后的window.HybridWebView.Init()放入一个export default function中即可
export default function(){
window.HybridWebView.Init();
}
然后再在index.html中加入。注意,HybridWebView.js要放在main.js的上面
<body>
<div id="app"></div>
<script type="module" src="/src/scripts/HybridWebView.js"></script>
<script type="module" src="/src/main.js"></script>
</body>
最后,编写vue组件
<script setup>
import { ref, onMounted } from "vue";
const name = ref("");
const persons = ref([]);
onMounted(async () => {
await flush_persons(); // 在mounted钩子中初始化persons列表
});
async function btn_add_person() {
await window.HybridWebView.InvokeDotNet("AddPerson", [name.value]); // 调用MAUI后端方法AddPerson,并传参
flush_persons();
}
async function flush_persons() {
persons.value = await window.HybridWebView.InvokeDotNet("GetAllPersons"); // 调用MAUI后端方法GetAllPersons
}
</script>
<template>
<input type="text" v-model="name" placeholder="person name" />
<button @click="btn_add_person">Add Person</button>
<li v-for="p in persons">
{{ p }}
</li>
</template>
<style scoped></style>
本文来自博客园,作者:HalloHerö,转载请注明原文链接:https://www.cnblogs.com/jimokelly/p/18615068