如何實現在react現有專案中嵌入Blazor?

tokengo發表於2023-01-19

如何實現在react現有專案中嵌入Blazor?

目前官方只提供了angular和react倆種示例所以本教程只將react教程

思路講解:

首先在現有react專案中我們可能某些元件是在Blazor中完成,但是我們沒辦法找到怎麼在react中輕量級使用blazor元件,可能會有人會使用iframe去載入Blazor專案,但是我不太喜歡這種方式,所以今天問了很多大佬,有大佬說可以直接在react使用Blazor元件的方式,並且找到了文件和示例(其實在Blazor文件中微軟已經提到了這個但是由於在文件的在下面的示例中可能沒什麼人去看 [文件直通車](ASP.NET Core Razor 元件 | Microsoft Learn))

首先流程

  1. 建立react專案

    npx create-react-app react-debug
    cd react-debug
    yarn or npm i
    

    將以下程式碼新增到App.js

import React, { useState } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
    const [nextCounterIndex, setNextCounterIndex] = useState(1);
    const [blazorCounters, setBlazorCounters] = useState([]);
    const addBlazorCounter = () => {
        const index = nextCounterIndex;
        setNextCounterIndex(index + 1);
        setBlazorCounters(blazorCounters.concat([{
            title: `Counter ${index}`,
            incrementAmount: index,
        }]));
    };
    const removeBlazorCounter = () => {
        setBlazorCounters(blazorCounters.slice(0, -1));
    };

    return (
        <div className="App">
            <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                    <button onClick={addBlazorCounter}>Add Blazor counter</button> &nbsp;
                    <button onClick={removeBlazorCounter}>Remove Blazor counter</button>
                </p>
    
                {blazorCounters.map(counter =>
                    <div key={counter.title}>
                        <my-blazor-counter title={counter.title} increment-amount={counter.incrementAmount}></my-blazor-counter> // 這裡將是渲染razor元件的地方 `my-blazor-counter` 是在razor中定義的,會在下面講到 
                    </div>
                )}
    
            </header>
        </div>
    );
}
export default App;

將以下引用新增到public/index.htmlMicrosoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js是Microsoft.AspNetCore.Components.CustomElements 生成的

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script src="_content/Microsoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js"></script> 
    <script src="_framework/blazor.webassembly.js"></script>
  </body>
</html>

  1. 建立WebAssembly專案
	mkdir webassembly 
	cd webassembly
	dotnet new blazorwasm-empty 

WebAssembly資料夾 並且在資料夾中建立 WebAssembly的空專案
需要確保專案是7.0 因為目前只支援6的預覽和7的正式版
安裝 Microsoft.AspNetCore.Components.CustomElements

	    <PackageReference="Microsoft.AspNetCore.Components.CustomElements" Version="7.0.2" />

Microsoft.AspNetCore.Components.CustomElements 是提供元件化的主要實現

修改Program.cs的程式碼

using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
// BlazorApp.Pages.Index可以修改成自己的渲染的razor元件
// my-blazor-counter就是上面提到的razor對應的標記 這樣就可以在react透過my-blazor-counter去渲染BlazorApp.Pages.Index元件的內容了
builder.RootComponents.RegisterCustomElement<webassembly.Pages.Index>("my-blazor-counter");
builder.RootComponents.Add<HeadOutlet>("head::after");

await builder.Build().RunAsync();

webassembly.Pages.Index元件相關程式碼

<h1>@Title</h1>

<p role="status">Current count: @currentCount</p>
<p>Increment amount: @IncrementAmount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;
    
    [Parameter] public string Title { get; set; } = "Blazor Counter";
    [Parameter] public int? IncrementAmount { get; set; }

    private void IncrementCount()
    {
        currentCount += IncrementAmount.GetValueOrDefault(1);
    }
}

<style>
    button {
        font-weight: bold;
        background-color: #7b31b8;
        color: white;
        border-radius: 4px;
        padding: 4px 12px;
        border: none;
    }

    button:hover {
        background-color: #9654cc;
        cursor: pointer;
    }

    button:active {
        background-color: #b174e4;
    }

</style>

如何檢視執行效果:

如果需要檢視執行效果有很多種方式比如透過程式碼將Blazor和react的代理到一塊這樣就可以一邊修改一邊預覽,

但是我現在做最簡單的
先將react build生成

yarn build

將build目錄下面的所有檔案複製到webassembly\wwwroot下,並且覆蓋index.html

然後執行dotnet程式 在webassembly目錄下執行

dotnet watch

將會開啟瀏覽器 ,效果入下圖,我們可以新增 Add Blazor counter

效果將是這樣,可以點選Click me將會條件 Current count數量 點選Remove Blazor counter將會刪除razor元件

好了效果差不多是這樣字,

透過這個案例我們可以知道 blazor也可以像react那樣嵌入在任何的現有專案中,並且使用方便,如果是vue的話目前還不知道是否支援 目前官方只提供了angular和react倆種實現,並且支援webassembly和server,當前教程是WebAssembly的實踐,Server會有所差異,

結尾

專案地址:239573049/Use-blazor-in-react (github.com)
官方示例: github地址
技術交流群:737776595

來著token的分享;

相關文章