Chapter 2.
Addon Basics -- frontend
1.1 frontend 資料夾介紹
在HydroOJ套件中 如果需要注射前端頁面 就需要建立frontend資料夾
my-addon/
├── frontend/
├── \[a-zA-Z0-9_\]+.page.tsx
其檔名格式為\[a-zA-Z0-9_\]+.page.tsx
(其中\[a-zA-Z0-9_\]為正規表達式 代表英文字母大小寫、數字、底線的任意組合)
只要符合此格式的檔案 都會被HydroOJ識別為前端頁面檔案 並運行
1.2 page.tsx 檔案介紹
I. 頁面檔案結構
import { addPage, NamedPage, AutoloadPage } from '@hydrooj/ui-default';
addPage(new AutoloadPage('SomeNameIGuess', () => {
console.log('This will appear on every page load!');
}));
addPage(new NamedPage(['homepage'], async () => {
console.log('This will appear on `homepage` page load!');
}));
addPage:用來注射頁面的函式AutoloadPage:用來注射到所有頁面的頁面類別NamedPage:用來注射到指定頁面的頁面類別 如何查詢頁面名稱 在瀏覽器打開你想注射的頁面後 開啟開發者工具DevTools(F12) 在元素Elements標籤中 查看最外圍<html>標籤的data-page屬性 即可看到頁面名稱
II. 注射 HTML/body
我們可以使用document物件來操作DOM 進行HTML/body的注射
import { addPage, NamedPage } from '@hydrooj/ui-default';
addPage(new NamedPage(['homepage'], async () => {
const newDiv = document.createElement('div');
newDiv.innerHTML = '<h1>Hello, HydroOJ!</h1>';
document.body.prepend(newDiv); // 將新元素注射到body的最前面
}));
也可以使用其他DOM操作方法來進行注射 如appendChild、insertBefore等
這裡就是js的基本DOM操作方法了 可以參考相關的js教學來學習更多 之後程設班官網應該也會有相關的教學文章
1.3 HTTP 請求 (Request API)
如果你需要向伺服器請求資源或API資料 可以使用request函式來進行HTTP請求
I. 基本用法
import { request } from '@hydrooj/ui-default';
// GET 請求
request.get('/api/endpoint').then(response => {
console.log(response.data);
});
// POST 請求
request.post('/api/endpoint', { key: 'value' }).then(response => {
console.log(response.data);
});
// PUT 請求
request.put('/api/endpoint', { key: 'value' });
// DELETE 請求
request.delete('/api/endpoint');
II. 進階選項
// 帶有自定義標頭
request.get('/api/data', {
headers: { 'X-Custom-Header': 'value' }
});
// 處理錯誤
request.get('/api/data')
.then(res => console.log('成功:', res.data))
.catch(err => console.log('錯誤:', err.message));
// 使用 async/await
async function fetchData() {
try {
const response = await request.get('/api/data');
console.log(response.data);
} catch (error) {
console.error('請求失敗:', error);
}
}
1.4 對話框 (Dialog API)
HydroOJ 提供多種對話框元件來彰顯使用者訊息或請求使用者操作
I. Alert / Confirm / Prompt
import { alert, confirm, prompt } from '@hydrooj/ui-default';
// 簡單提示
alert('這是一個提示訊息');
// 確認對話框(返回 boolean)
confirm('確定要刪除嗎?').then(yes => {
if (yes) {
console.log('使用者按下確認');
}
});
// 輸入對話框(返回輸入值或 null)
prompt('請輸入內容:').then(value => {
if (value !== null) {
console.log('使用者輸入了:', value);
}
});
II. 高級對話框
import { Dialog, ActionDialog, InfoDialog } from '@hydrooj/ui-default';
// 訊息対話框
new InfoDialog({
title: '訊息',
message: '這是一個訊息對話框'
}).show();
// 帶有動作按鈕的對話框
new ActionDialog({
$body: document.createElement('div'),
onAction: (val) => {
console.log('使用者選擇了:', val);
}
}).show();
1.5 通知系統 (Notification API)
在頁面上方顯示簡短的通知訊息
import { Notification } from '@hydrooj/ui-default';
// 成功通知
Notification.success('操作成功!');
// 錯誤通知
Notification.error('操作失敗!');
// 警告通知
Notification.warning('請注意!');
// 資訊通知
Notification.info('這是一個資訊通知');
1.6 多國語系 (i18n)
在前端代碼中使用多國語系字符串
import { i18n } from '@hydrooj/ui-default';
// 獲取翻譯文本
const message = i18n('homepage');
console.log(message); // 對應當前語言的翻譯
// 帶有參數的翻譯(如果支援)
const greeting = i18n('greeting', { name: 'Alice' });
1.7 頁面系統進階用法
I. 頁面生命週期
import { NamedPage } from '@hydrooj/ui-default';
const page = new NamedPage(
'problem_detail',
async (pageName) => {
console.log('頁面載入前執行');
},
async (pageName) => {
console.log('頁面載入後執行');
}
);
II. 多頁面匹配
import { NamedPage } from '@hydrooj/ui-default';
// 在多個頁面上運行相同的代碼
addPage(new NamedPage(['homepage', 'problem_list', 'contest_list'], () => {
console.log('在主頁或列表頁上運行');
}));
III. 懶加載模塊
import { NamedPage } from '@hydrooj/ui-default';
// 指定模塊名稱以進行懶加載
const page = new NamedPage(
'heavy_page',
'my_heavy_module', // 模塊名稱
async (pageName) => {
console.log('懶加載的模塊執行');
}
);
以下是 @hydrooj/ui-default 中一些其他常用的函式
| 套件名稱 | 作用說明 |
|---|---|
request | 用來進行HTTP請求(GET/POST/PUT/DELETE) |
i18n(key) | 用來進行多國語系翻譯 |
Dialog / ActionDialog / InfoDialog | 對話框元件 |
Notification.success() / error() / warning() / info() | 通知訊息 |
delay(ms) | 延遲指定毫秒數 |
pjax(url) | PJAX 導航(無整頁刷新) |
tpl / rawHtml | HTML 模板處理 |
getTheme() | 獲取當前主題 |
詳細的 API 參考請查看附錄:前端 API 完整參考
