開發工具插件支持
Vaadin Development Tools 已經被替換為 Copilot。
開發工具彈窗支持透過由開發者創建的插件來添加自定義分頁。用插件添加自定義分頁將需要一個實現 MessageHandler 的客戶端元素和一個實現 DevToolsMessageHandler 的 Java 類。
客戶端與服務器端之間的數據會透過提供的消息處理程序 API,以命令消息 的形式進行傳送。
創建客戶端元素
客戶端元素將被渲染在 Development Tools 視窗自己的分頁內。首先創建一個實現 MessageHandler 的元素,例如:
Source code
my-tool.ts
my-tool.ts@customElement('my-tool')
export class MyTool extends LitElement implements MessageHandler {
render() {
return html`<div>This will be rendered in the tab</div>`;
}
}然後將創建的元素註冊為插件並為其添加排行:
Source code
TypeScript
let devTools: DevToolsInterface;
...
export class MyTool extends LitElement implements MessageHandler {
...
}
const plugin: DevToolsPlugin = {
init: function (devToolsInterface: DevToolsInterface): void {
devTools = devToolsInterface;
devTools.addTab('My Tool Tab', 'my-tool');
}
};
(window as any).Vaadin.devToolsPlugins.push(plugin);DevToolsInterface 的引用會被儲存,以便未來用於與服務器通信。現在 MyTool 可以在必要時擴展功能。
如果客戶端插件實現了 activate() 或 deactivate() 方法,當插件分頁被選中時會調用 activate,當切換至其他分頁時會調用 deactivate。
|
Note
|
插件腳本文件若僅在專案內使用,應位於 ./frontend/ 資料夾下;若作為插件包進行開發,則應位於 ./src/main/resources/META-INF/frontend/ 下。
|
創建 Java 組件
在服務器端,插件需導入 TS 文件,並透過 Java 服務提供者定義插件載入方法。客戶端模組應設為 developmentOnly,具體方式如下:
Source code
Java
package com.my.app;
@JsModule(value = "./my-tool.ts", developmentOnly = true)
public class MyToolPlugin implements DevToolsMessageHandler {
}Java 服務提供者需要在下列路徑的文件中定義插件的完整名稱:.src/main/resources/META-INF/services/com.vaadin.base.devserver.DevToolsMessageHandler。
Source code
com.my.app.MyToolPlugin服務端到客戶端通信
服務端接口 DevToolsMessageHandler 提供兩個方法:handleConnect(DevToolsInterface devToolsInterface) 和 handleMessage(String command, JsonObject data, DevToolsInterface devToolsInterface)。
Development Tools 彈窗於瀏覽器建立時,會調用 handleConnect。此方法提供了用於與 Development Tools 互動的介面 DevToolsInterface。
如需要向客戶端發送數據,可使用 send(String command, JsonObject data) 方法。command 為客戶端插件已知的識別字串,而 data 則為接收方可理解的內容。
向 Development Tools 彈窗發送命令的示例如下:
Source code
Java
@JsModule(value = "./my-tool.ts", developmentOnly = true)
public class MyToolPlugin implements DevToolsMessageHandler {
@Override
public void handleConnect(DevToolsInterface devToolsInterface) {
devToolsInterface.send("myplugin-init", null);
}
}相關的客戶端處理程序可能如下所示:
Source code
TypeScript
export class MyTool extends LitElement implements MessageHandler {
handleMessage(message: ServerMessage): boolean {
if (message.command === 'myplugin-init') {
// 執行操作
return true; // 標記消息已處理
}
return false; // 消息未處理
}
}插件之間沒有命名空間區隔,所有插件都可收到所有消息,因此命令命名不應泛用(如不應用 init),建議命令以插件獨有名稱為前綴。
當消息被 handleMessage 處理時將返回 true,用以防止其他插件收到該消息;若未處理,則返回 false,讓其他插件有機會接收消息。
客戶端到服務端通信
若需從客戶端向服務端通信,客戶端介面 DevToolsInterface 提供了 send(command: string, data: any): void 方法。
例如按鈕點擊向服務端發送消息時模板可能如下:
Source code
TypeScript
let devTools: DevToolsInterface;
export class MyTool extends LitElement implements MessageHandler {
render() {
return html`<button @click=${this.informServer}>Click this for magic</button>`;
}
informServer() {
devTools.send("myplugin-inform", {text: 'Hello'});
}
}服務端處理消息時可能如下所示:
Source code
Java
public class MyToolPlugin implements DevToolsMessageHandler {
@Override
public boolean handleDevToolsMessage(String command, JsonObject data, DevToolsInterface devToolsInterface) {
if (command.equals("myplugin-inform")) {
System.out.println("The information text is " + data.getString("text"));
return true;
}
return false;
}
}handleDevToolsMessage 處理消息時會返回 true,避免其他插件收到此消息;若未處理,則返回 false,其他插件將可接收。
完整插件範例
上述範例片段可能有些混亂。以下提供一個完整插件範例:
Source code
MyTool.java
MyTool.javapackage com.my.app.MyToolPlugin;
import com.vaadin.base.devserver.DevToolsInterface;
import com.vaadin.base.devserver.DevToolsMessageHandler;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.server.VaadinSession;
import elemental.json.Json;
import elemental.json.JsonObject;
@JsModule(value = "./my-tool.ts", developmentOnly = true)
public class MyTool implements DevToolsMessageHandler {
@Override
public void handleConnect(DevToolsInterface devToolsInterface) {
devToolsInterface.send("myplugin-init", null);
}
@Override
public boolean handleMessage(String command, JsonObject data,
DevToolsInterface devToolsInterface) {
if (command.equals("myplugin-query")) {
String text = data.getString("text");
JsonObject responseData = Json.createObject();
responseData.put("text", "Response for " + text);
devToolsInterface.send("myplugin-response", responseData);
System.out.println(text);
return true;
}
return false;
}
}(以下程式碼因長度限制而略略省略,詳見前文原文。)