共用方式為


ASP.NET Core Blazor 啟動

注意

這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊不做任何明示或默示的保證。

如需目前的版本,請參閱 本文的 .NET 9 版本。

本文說明 Blazor 應用程式啟動設定。

如需用於伺服器端開發的 ASP.NET Core 應用程式組態的一般指引,請參閱 ASP.NET Core 中的組態

啟動程序與設定

Blazor 啟動程序透過 Blazor 指令碼 (blazor.*.js) 自動化且非同步,其中的 * 預留位置為:

  • web 為 Blazor Web App。
  • server 用於 Blazor Server 應用程式
  • webassembly 用於 Blazor WebAssembly 應用程式

Blazor 啟動程序透過 Blazor 指令碼 (blazor.*.js) 自動化且非同步,其中的 * 預留位置為:

  • server 用於 Blazor Server 應用程式
  • webassembly 用於 Blazor WebAssembly 應用程式

如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

若要手動啟動 Blazor:

Blazor Web App:

  • autostart="false" 屬性和值新增至 Blazor<script> 標籤。
  • 將呼叫 Blazor.start() 的指令碼放在 Blazor<script> 標籤後面和結束 </body> 標籤內。
  • 將靜態伺服器端轉譯 (靜態 SSR) 選項放在 ssr 屬性中。
  • 將伺服器端 Blazor-SignalR 線路選項放在 circuit 屬性中。
  • 將用戶端 WebAssembly 選項放在 webAssembly 屬性中。
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ssr: {
      ...
    },
    circuit: {
      ...
    },
    webAssembly: {
      ...
    }
  });
  ...
</script>

獨立 Blazor WebAssembly 和 Blazor Server:

  • autostart="false" 屬性和值新增至 Blazor<script> 標籤。
  • 將呼叫 Blazor.start() 的指令碼放在 Blazor<script> 標籤後面和結束 </body> 標籤內。
  • 您可以在 Blazor.start() 參數中提供其他選項。
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ...
  });
  ...
</script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

JavaScript 初始設定式

JavaScript (JS) 初始設定式會在 Blazor 應用程式載入前後執行邏輯。 JS 初始設定式在下列狀況中會很有幫助:

  • 自訂 Blazor 應用程式載入方式。
  • 在 Blazor 啟動前先初始化程式庫。
  • 設定 Blazor 設定值。

系統會在建置過程中偵測 JS 初始設定式,並自動將其匯入。 使用 JS 初始設定式通常會移除在使用 時,Razor的需求。

若要定義 JS 初始設定式,請將 JS 模組新增至名為 {NAME}.lib.module.js 的專案,其中 {NAME} 預留位置是組件名稱、程式庫名稱或封裝識別碼。 將檔案放在專案的 Web 根目錄中 (通常是 wwwroot 資料夾)。

對於 Blazor Web App:

  • beforeWebStart(options):在 Blazor Web App 開始之前呼叫。 例如,beforeWebStart 會用來自訂載入程序、記錄層級和其他選項。 接收 Blazor 網頁選項 (options)。
  • afterWebStarted(blazor):在所有 beforeWebStart Promise 解析完畢後呼叫。 例如,afterWebStarted 可用來註冊 Blazor 事件接聽程式和自訂事件類型。 Blazor 執行個體會以引數的形式傳遞至 afterWebStarted (blazor)。
  • beforeServerStart(options, extensions):在第一個伺服器執行階段啟動之前呼叫。 接收發佈期間新增的 SignalR 電路啟動選項 (options) 和任何擴充功能 (extensions)。
  • afterServerStarted(blazor):在第一個互動式伺服器執行階段啟動之後呼叫。
  • beforeWebAssemblyStart(options, extensions):在互動式 WebAssembly 執行階段啟動之前呼叫。 接收發佈期間新增的 Blazor 選項 (options) 和任何延伸模組 (extensions)。 例如,選項可以指定使用自訂開機資源載入器.
  • afterWebAssemblyStarted(blazor):在啟動互動式 WebAssembly 執行階段後進行呼叫。

注意

舊版 JS 初始設定式 (beforeStartafterStarted) 預設不會在 Blazor Web App 中叫用。 您可以讓舊版初始設定式透過 enableClassicInitializers 選項執行。 不過,舊版初始設定式執行無法預測。

<script>
  Blazor.start({ enableClassicInitializers: true });
</script>

由於 .NET 8 和 9 的框架錯誤(dotnet/aspnetcore #54049),因此在呼叫 或 Blazor 時,beforeWebAssemblyStart(options, extensions) 腳本必須手動啟動。 如果伺服器應用程式尚未使用 WebAssembly (Blazor) 組態手動啟動webAssembly: {...},請使用下列內容更新App伺服器專案中的元件。

在 中 Components/App.razor,移除現有的 Blazor<script> 標記:

- <script src="_framework/blazor.web.js"></script>

<script> 標籤替換為以下標記:該標記以 WebAssembly(Blazor)的配置手動啟動webAssembly: {...}

<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
    Blazor.start({
        webAssembly: {}
    });
</script>

針對 Blazor Server、Blazor WebAssembly 和 Blazor Hybrid 應用程式:

  • beforeStart(options, extensions):在 Blazor 開始之前呼叫。 例如,beforeStart 會用來自訂載入程序、記錄層級,以及裝載模型專屬的其他選項。
    • 用戶端,beforeStart 會接收發佈期間新增的 Blazor 選項 (options) 和任何延伸模組 (extensions)。 例如,選項可以指定使用自訂開機資源載入器.
    • 伺服器端。beforeStart 會接收 SignalR 線路啟動選項 (options)。
    • BlazorWebView 中,不會傳遞任何選項。
  • afterStarted(blazor):在 Blazor 就緒之後,即可開始接收來自 JS 的呼叫。 例如,afterStarted 是進行 JS Interop 呼叫並註冊自訂元素,藉此用來初始化程式庫。 Blazor 執行個體會以引數的形式傳遞至 afterStarted (blazor)。

其他 .NET WebAssembly 執行階段回呼函數:

  • onRuntimeConfigLoaded(config):下載開機設定時呼叫。 允許應用程式在執行階段開始之前修改參數(config)(該參數是從 MonoConfig 來的 dotnet.d.ts):

    export function onRuntimeConfigLoaded(config) {
      // Sample: Enable startup diagnostic logging when the URL contains 
      // parameter debug=1
      const params = new URLSearchParams(location.search);
      if (params.get("debug") == "1") {
        config.diagnosticTracing = true;
      }
    }
    
  • onRuntimeReady({ getAssemblyExports, getConfig }):在 .NET WebAssembly 執行階段已啟動之後呼叫(參數是來自 RuntimeAPIdotnet.d.ts):

    export function onRuntimeReady({ getAssemblyExports, getConfig }) {
      // Sample: After the runtime starts, but before Main method is called, 
      // call [JSExport]ed method.
      const config = getConfig();
      const exports = await getAssemblyExports(config.mainAssemblyName);
      exports.Sample.Greet();
    }
    

這兩個回調函數都可以傳回 Promise,並且在啟動繼續之前會等待這個 Promise。

針對檔案名稱:

  • 如果取用 JS 初始設定式作為專案中的靜態資產,請使用格式 {ASSEMBLY NAME}.lib.module.js,其中 {ASSEMBLY NAME} 預留位置是應用程式的組件名稱。 例如,將專案的檔案命名為 BlazorSample.lib.module.js,其組件名稱為 BlazorSample。 將檔案放在應用程式的 wwwroot 資料夾中。
  • 如果 JS 初始設定式是從 RCL 取用,請使用格式 {LIBRARY NAME/PACKAGE ID}.lib.module.js,其中 {LIBRARY NAME/PACKAGE ID} 預留位置是專案的程式庫名稱或套件識別碼。 例如,將 RCL 的檔案命名為 RazorClassLibrary1.lib.module.js,其封裝識別碼為 RazorClassLibrary1。 將檔案放在程式庫的 wwwroot 資料夾中。

對於 Blazor Web App:

下列範例示範 JS 初始化器,這些初始化器會在 Blazor Web App 啟動之前和之後載入自訂指令碼,方法是將它們附加到 <head> 中的 beforeWebStartafterWebStarted

export function beforeWebStart() {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'beforeStartScripts.js');
  document.head.appendChild(customScript);
}

export function afterWebStarted() {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'afterStartedScripts.js');
  document.head.appendChild(customScript);
}

上述 beforeWebStart 範例只會保證自訂指令碼在 Blazor 啟動之前載入。 這無法保證指令碼中等候的 Promise 會在 Blazor 啟動之前完成執行。

針對 Blazor Server、Blazor WebAssembly 和 Blazor Hybrid 應用程式:

下列範例示範 JS 初始設定式,這些初始設定式會在 Blazor 啟動之前和之後載入自訂指令碼,方法是將這些指令碼新增至 <head>beforeStart 中的 afterStarted

export function beforeStart(options, extensions) {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'beforeStartScripts.js');
  document.head.appendChild(customScript);
}

export function afterStarted(blazor) {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'afterStartedScripts.js');
  document.head.appendChild(customScript);
}

上述 beforeStart 範例只會保證自訂指令碼在 Blazor 啟動之前載入。 這無法保證指令碼中等候的 Promise 會在 Blazor 啟動之前完成執行。

注意

MVC 和 Razor Pages 應用程式不會自動載入 JS 初始設定式。 不過,開發人員程式碼可以包含指令碼來擷取應用程式的資訊清單,並觸發 JS 初始設定式的載入。

如需 JS 初始設定式的範例,請參閱下列資源:

注意

.NET 參考來源的文件鏈接通常會載入存放庫的預設分支,該分支代表目前針對下一版 .NET 的開發工作。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

確定程式庫會依特定順序載入

根據自訂指令碼應載入的順序,將這些指令碼依次附加到 <head>beforeStartafterStarted 中。

下列範例會在 script1.js 之前載入 script2.js,以及在 script3.js 之前載入 script4.js

export function beforeStart(options, extensions) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script1.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script2.js');
    document.head.appendChild(customScript2);
}

export function afterStarted(blazor) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script3.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script4.js');
    document.head.appendChild(customScript2);
}

匯入其他模組

使用 import 初始設定式檔案中的最上層 JS 陳述式來匯入其他模組。

additionalModule.js

export function logMessage() {
  console.log('logMessage is logging');
}

在 JS 初始設定式檔案 (.lib.module.js) 中:

import { logMessage } from "/additionalModule.js";

export function beforeStart(options, extensions) {
  ...

  logMessage();
}

匯入映射圖

匯入對應 由 ASP.NET Core 和 Blazor 支援。

文件準備就緒時初始化 Blazor

下列範例會在文件就緒時啟動 Blazor:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    Blazor.start();
  });
</script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

手動啟動後產生的Promise鏈結

若要執行其他工作,例如 JS Interop 初始化,請使用 then 串接至手動 Promise 應用程式啟動過程中所產生的 Blazor:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start().then(function () {
    ...
  });
</script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

注意

如需程式庫在 Blazor 啟動之後自動執行其他工作,請使用 JavaScript 初始設定式。 使用 JS 初始設定式不需要函式庫的使用者將 JS 的呼叫鏈結到 Blazor 的手動啟動。

載入用戶端開機資源

當應用程式在瀏覽器中載入時,應用程式會從伺服器下載開機資源:

  • 啟動應用程式的 JavaScript 程式碼
  • .NET 執行階段和組件
  • 針對地區的特定資料

自訂如何使用 loadBootResource API 載入這些開機資源。 loadBootResource 函式會覆寫內建的開機資源載入機制。 針對下列案例使用 loadBootResource

  • 從 CDN 載入靜態資源,例如時區資料或 dotnet.wasm
  • 針對不支援從伺服器擷取壓縮內容的主機,使用 HTTP 要求載入壓縮組件,並在用戶端上將其解壓縮。
  • 將每個 fetch 要求重新導向至新名稱,為資源設置新的別名。

注意

外部來源必須傳回瀏覽器所需的跨原始資源共用 (CORS) 標頭,以允許跨原始來源資源載入。 CDN 通常會提供所需的標題。

loadBootResource 參數出現在下表中。

參數 描述
type 資源的類型。 允許的類型包括:assemblypdbdotnetjsdotnetwasmtimezonedata。 您只需要指定自訂行為的類型。 未指定給 loadBootResource 的類型是架構根據其預設載入行為載入的。 dotnetjs 開機資源 (dotnet.*.js) 必須傳回預設載入行為的 null,或 dotnetjs 開機資源的來源 URI。
name 資源名稱。
defaultUri 資源的相對或絕對 URI。
integrity 代表回應中預期內容的完整性字串。

loadBootResource 函式可以傳回 URI 字串來覆寫載入流程。 在下列範例中,來自 bin/Release/{TARGET FRAMEWORK}/wwwroot/_framework 的下列檔案是從位於 https://cdn.example.com/blazorwebassembly/{VERSION}/ 的 CDN 提供:

  • dotnet.*.js
  • dotnet.wasm
  • 時區資料

{TARGET FRAMEWORK} 佔位符是目標框架名稱(例如,net7.0)。 {VERSION} 預留位置是共用架構版本 (例如,7.0.0)。

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
        switch (type) {
          case 'dotnetjs':
          case 'dotnetwasm':
          case 'timezonedata':
            return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
        }
      }
    }
  });
</script>

獨立 Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
      switch (type) {
        case 'dotnetjs':
        case 'dotnetwasm':
        case 'timezonedata':
          return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
      }
    }
  });
</script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

若要自訂的不只是開機資源的 URL,loadBootResource 函式可以直接呼叫 fetch 並傳回結果。 下列範例會將自訂 HTTP 標頭新增至輸出要求。 若要保留預設完整性檢查行為,請傳遞 integrity 參數。

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        if (type == 'dotnetjs') {
          return null;
        } else {
          return fetch(defaultUri, {
            cache: 'no-cache',
            integrity: integrity,
            headers: { 'Custom-Header': 'Custom Value' }
          });
        }
      }
    }
  });
</script>

獨立 Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      if (type == 'dotnetjs') {
        return null;
      } else {
        return fetch(defaultUri, {
          cache: 'no-cache',
          integrity: integrity,
          headers: { 'Custom-Header': 'Custom Value' }
        });
      }
    }
  });
</script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

loadBootResource 函式傳回 null 時,Blazor 會使用資源的預設載入行為。 例如,上述程式碼對於開機資源 null 會傳回 dotnetjs (dotnet.*.js),因為開機資源 dotnetjs 必須要麼傳回預設載入行為的 null,要麼提供開機資源 dotnetjs 的來源 URI。

loadBootResource 函式也可以傳回 Response 承諾(Promise)。 如需範例,請參閱裝載和部署 ASP.NET Core Blazor WebAssembly

如需詳細資訊,請參閱 ASP.NET Core Blazor WebAssembly .NET 套件組合快取和完整性檢查失敗

控制 C# 程式碼中的標頭

使用下列方法,控制 C# 程式碼中啟動時的標頭。

在下列範例中,內容安全性原則 (CSP) 會透過 CSP 標頭套用至應用程式。 {POLICY STRING} 佔位符是 CSP 策略字串。 如需 CSP 的詳細資訊,請參閱針對 ASP.NET Core Blazor 強制執行內容安全性原則

注意

回應啟動之後,無法設定標頭。 本節中的方法只會在響應開始之前設定標頭,因此此處所述的方法是安全的。 如需詳細資訊,請參閱 ASP.NET Core Blazor 應用程式中 IHttpContextAccessor/HttpContext。

伺服器端和預先渲染用戶端情境

使用 ASP.NET Core 中介軟體來控制標頭集合。

Program 檔案中:

Startup.ConfigureStartup.cs 中:

app.Use(async (context, next) =>
{
    context.Response.Headers.Append("Content-Security-Policy", "{POLICY STRING}");
    await next();
});

上述範例使用內嵌中介軟體,但您也可以建立自訂中介軟體類別,並使用 Program 檔案中的擴充方法呼叫中介軟體。 如需詳細資訊,請參閱撰寫自訂 ASP.NET Core 中介軟體

不經預渲染的客戶端開發

StaticFileOptions 傳遞至 MapFallbackToFile,指定 OnPrepareResponse 階段中的回應標頭。

在伺服器端 Program 檔案中:

Startup.ConfigureStartup.cs 中:

var staticFileOptions = new StaticFileOptions
{
    OnPrepareResponse = context =>
    {
        context.Context.Response.Headers.Append("Content-Security-Policy", 
            "{POLICY STRING}");
    }
};

...

app.MapFallbackToFile("index.html", staticFileOptions);

用戶端載入指標

載入指標會顯示應用程式正常載入,而且用戶應該等到載入完成為止。

Blazor Web App 載入指標

應用程式中使用的 Blazor WebAssembly 載入指標不存在於從專案範本建立的 Blazor Web App 應用程式中。 通常,互動式 WebAssembly 元件不需要顯示載入指示,因為 Blazor Web App會在伺服器上預先呈現用戶端元件,以加快初始載入速度。 針對混合轉譯模式的情況,架構或開發人員程式碼也必須小心以避免下列問題:

  • 在相同轉譯頁面上顯示多個載入指示器。
  • 在 .NET WebAssembly 執行階段載入期間,不慎丟棄預渲染的內容。

未來的 .NET 版本可能會提供架構型載入指標。 同時,您可以將自訂載入指標新增至 Blazor Web App。

使用逐元件的互動式WebAssembly渲染和預先渲染

此案例適用於個別元件的互動式 WebAssembly 轉譯(@rendermode InteractiveWebAssembly 套用至個別元件)。

ContentLoading應用程式的Layout資料夾中建立.Client元件,並呼叫OperatingSystem.IsBrowser

  • false 時,顯示載入指標。
  • true 時,轉譯要求元件的內容。

若要載入指標的 CSS 樣式,請將樣式新增至 <head> 元件的 HeadContent 內容。 如需詳細資訊,請參閱控制 ASP.NET Core Blazor 應用程式中的標題內容

Layout/ContentLoading.razor

@if (!RendererInfo.IsInteractive)
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}
@if (!OperatingSystem.IsBrowser())
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}

如果您還沒有專案中的資料夾Layout.Client,請將資料夾的Layout命名空間新增至_Imports.razor檔案。 在下列範例中,專案的命名空間為 BlazorSample.Client

@using BlazorSample.Client.Layout

在採用互動式 WebAssembly 呈現的元件中,使用 Razor 元件包裹該元件的 ContentLoading 標記。 以下範例展示使用Counter元件的方式,此元件是透過Blazor Web App專案範本建立的應用程式。

Pages/Counter.razor

@page "/counter"
@rendermode InteractiveWebAssembly

<PageTitle>Counter</PageTitle>

<ContentLoading>
    <h1>Counter</h1>

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

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

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

使用預渲染的全域互動式 WebAssembly 轉譯

此情境適用於全球互動式 WebAssembly 的渲染與預渲染(@rendermode="InteractiveWebAssembly" 用於 HeadOutlet 元件中的 RoutesApp 元件上)。

ContentLoading應用程式的Layout資料夾中建立.Client元件,並呼叫RendererInfo.IsInteractive

  • false 時,顯示載入指標。
  • true 時,轉譯要求元件的內容。

若要載入指標的 CSS 樣式,請將樣式新增至 <head> 元件的 HeadContent 內容。 如需詳細資訊,請參閱控制 ASP.NET Core Blazor 應用程式中的標題內容

Layout/ContentLoading.razor

@if (!RendererInfo.IsInteractive)
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}
@if (!OperatingSystem.IsBrowser())
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}

如果您還沒有專案中的資料夾Layout.Client,請將資料夾的Layout命名空間新增至_Imports.razor檔案。 在下列範例中,專案的命名空間為 BlazorSample.Client

@using BlazorSample.Client.Layout

MainLayout 專案的 Layout/MainLayout.razor 元件(.Client)中,將 Body 屬性(@Body)包裝為 ContentLoading 元件:

Layout/MainLayout.razor 中:

+ <ContentLoading>
    @Body
+ </ContentLoading>

全域互動式 WebAssembly 轉譯而不預先呈現

此案例適用於全域互動式 WebAssembly 渲染且無需預先呈現(於 @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" 元件中的 HeadOutletRoutes 元件上的 App)。

JavaScript 初始化運算式 新增至應用程式。 在下列 JavaScript 模組檔名範例中 {ASSEMBLY NAME} ,佔位元元是伺服器項目的元件名稱(例如 , BlazorSample。 模組 wwwroot 所在的資料夾是 wwwroot 伺服器端專案中的資料夾,而不是 .Client 專案。

下列範例會使用 progress 指標,不會顯示 將用戶端開機資源傳遞至客戶端的實際進度,但作為進一步開發中的一般方法,它可用於使進度指標顯示載入應用程式開機資源的實際進度。

wwwroot/{ASSEMBLY NAME}.lib.module.js

export function beforeWebStart(options) {
  var progress = document.createElement("progress");
  progress.id = 'loadingIndicator';
  progress.ariaLabel = 'Blazor loading…';
  progress.style = 'position:absolute;top:50%;left:50%;margin-right:-50%;' +
    'transform:translate(-50%,-50%);';
  document.body.appendChild(progress);
}

export function afterWebAssemblyStarted(blazor) {
  var progress = document.getElementById('loadingIndicator');
  progress.remove();
}

由於 .NET 8 和 9 中的架構錯誤(dotnet/aspnetcore #54049), Blazor 腳本必須手動啟動。 如果伺服器應用程式尚未使用 WebAssembly (Blazor) 組態手動啟動webAssembly: {...},請使用下列內容更新App伺服器專案中的元件。

在 中 Components/App.razor,移除現有的 Blazor<script> 標記:

- <script src="_framework/blazor.web.js"></script>

<script> 標籤替換為以下標記:該標記以 WebAssembly(Blazor)的配置手動啟動webAssembly: {...}

<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
    Blazor.start({
        webAssembly: {}
    });
</script>

如果您注意到載入指標的移除與第一頁轉譯之間有短暫延遲,可以在 OnAfterRenderAsync 元件的MainLayout中呼叫指標移除,以確保在轉譯後移除指標。 如需詳細資訊和程式代碼範例,請參閱記錄載入指標的方法,該指標可與全域互動式WebAssembly搭配運作,而不預先呈現 (dotnet/AspNetCore.Docs#35111)。

Blazor WebAssembly 應用程式載入進度

專案範本包含可調整向量圖形 (SVG) 和顯示應用程式載入進度的文字指標。

進度指標是使用 Blazor 提供的兩個 CSS 自訂屬性 (變數),搭配 HTML 和 CSS 所實作:

  • --blazor-load-percentage:已載入的應用程式檔案百分比。
  • --blazor-load-percentage-text:已載入的應用程式檔案百分比,四捨五入為最接近的整數。

使用上述 CSS 變數,您可以建立符合應用程式樣式的自訂進度指標。

在以下範例中:

  • resourcesLoaded 是應用程式啟動期間所載入資源的瞬間計數。
  • totalResources 是要載入的資源總數。
const percentage = resourcesLoaded / totalResources * 100;
document.documentElement.style.setProperty(
  '--blazor-load-percentage', `${percentage}%`);
document.documentElement.style.setProperty(
  '--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`);

預設的圓形進度指標是在 wwwroot/index.html 檔案的 HTML 中實作:

<div id="app">
    <svg class="loading-progress">
        <circle r="40%" cx="50%" cy="50%" />
        <circle r="40%" cx="50%" cy="50%" />
    </svg>
    <div class="loading-progress-text"></div>
</div>

若要檢閱預設進度指標的專案範本標記和樣式,請參閱 ASP.NET Core 參考來源:

注意

.NET 參考來源的文件鏈接通常會載入存放庫的預設分支,該分支代表目前針對下一版 .NET 的開發工作。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

下列範例展示如何實作線性進度指標,而不是使用預設的圓形進度指標。

將下列樣式新增至 wwwroot/css/app.css

.linear-progress {
    background: silver;
    width: 50vw;
    margin: 20% auto;
    height: 1rem;
    border-radius: 10rem;
    overflow: hidden;
    position: relative;
}

.linear-progress:after {
    content: '';
    position: absolute;
    inset: 0;
    background: blue;
    scale: var(--blazor-load-percentage, 0%) 100%;
    transform-origin: left top;
    transition: scale ease-out 0.5s;
}

CSS 變數 (var(...)) 用來將 --blazor-load-percentage 的值傳遞至藍色虛擬元素的 scale 屬性,指出應用程式檔案的載入進度。 當應用程式載入時,--blazor-load-percentage 會自動更新,以動態方式變更進度指示器的視覺效果表示法。

wwwroot/index.html 中,移除 <div id="app">...</div> 中的預設 SVG 四捨五入指標,並將其取代為下列標記:

<div class="linear-progress"></div>

設定 .NET WebAssembly 執行階段

在進階程式設計案例中,會使用具有 configureRuntime 執行階段主機建立器的 dotnet 函式來設定 .NET WebAssembly 執行階段。 例如,dotnet.withEnvironmentVariable 會設定環境變數:

  • 配置 .NET WebAssembly 執行階段。
  • 變更 C 程式庫的行為。

注意

GitHub 存放庫中有一項 dotnet/runtime 文件要求擱置,以取得有關於設定 .NET WebAssembly 執行階段或影響 C 程式庫行為的環境變數之詳細資訊。 儘管文件請求仍在處理中,但您可以在 Question/request for documentation on .NET WASM runtime env vars (dotnet/runtime #98225)這個請求中取得更多資訊和其他資源的交叉連結。

configureRuntime 函式也可用來啟用與瀏覽器設定檔的整合

以下範例中的預留位置是用來設定環境變數的:

  • {BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構
  • {NAME} 預留位置是環境變數的名稱。
  • {VALUE} 預留位置是環境變數的值。

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      configureRuntime: dotnet => {
        dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
      }
    }
  });
</script>

獨立 Blazor WebAssembly:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureRuntime: dotnet => {
      dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
    }
  });
</script>

注意

.NET 執行階段執行個體可以使用 .NET WebAssembly 執行階段 API(Blazor.runtime)進行存取。 例如,您可以使用 Blazor.runtime.runtimeBuildInfo.buildConfiguration 取得應用程式的組建設定。

如需 .NET WebAssembly 執行階段設定的詳細資訊,請參閱 dotnet.d.ts GitHub 存放庫dotnet/runtime執行階段的 TypeScript 定義檔案 ()。

注意

.NET 參考來源的文件鏈接通常會載入存放庫的預設分支,該分支代表目前針對下一版 .NET 的開發工作。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

停用強化的導航與表單處理功能

本章節適用於 Blazor Web Apps。

若要停用 增強式導覽和表單處理,請針對 disableDomPreservationtrue 設定為 Blazor.start

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    ssr: { disableDomPreservation: true }
  });
</script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼路徑和檔案名稱。 如需指令碼的位置,請參閱 ASP.NET Core Blazor 專案結構

其他資源