Widget 開發三步驟
1. 建立 Widget 類別
<?php
namespace app\components; // 建議放在 components 目錄
use yii\base\Widget;
use yii\helpers\Html;
class HelloWidget extends Widget {
public $message = 'Hello World'; // 公開屬性,可從外部傳入
public function init() {
parent::init();
if ($this->message === null) {
$this->message = 'Hello World'; // 預設值
}
}
public function run() {
// 回傳輸出內容 (而非直接 echo)
return Html::encode($this->message);
}
}
?>
2. 視圖中呼叫 Widget
<?php
use app\components\HelloWidget;
?>
<!-- 靜態呼叫 -->
<?= HelloWidget::widget(['message' => 'Good morning']) ?>
<!-- 或在配置陣列中使用 -->
<?= HelloWidget::widget([
'message' => '動態訊息 ' . date('H:i:s'),
// 也可傳遞其他自訂屬性
]) ?>
3. 進階:Widget 內部渲染視圖檔
<?php
namespace app\components;
use yii\base\Widget;
class AdvancedWidget extends Widget {
public $items = [];
public function run() {
// 渲染獨立視圖檔 @app/views/widgets/advanced.php
return $this->render('advanced', [
'items' => $this->items,
'widget' => $this,
]);
}
}
?>
視圖檔範例 `views/widgets/advanced.php`
<div class="widget-advanced">
<h3>進階 Widget 範例</h3>
<ul>
<?php foreach ($items as $item): ?>
<li><?= Html::encode($item) ?></li>
<?php endforeach; ?>
</ul>
</div>
Widget 設計最佳實務
- 單一職責:每個 Widget 專注單一 UI 功能
- 無副作用:`run()` 只回傳字串,不直接輸出、不修改全域狀態
- 資料隔離:透過屬性注入資料,避免直接存取 `$_GET`/`$_POST`
- 快取友善:支援 `yii\base\Widget::begin()`/`end()` 片段快取
- 資產管理:覆寫 `getAssetBundle()` 註冊專屬 CSS/JS
常見應用場景
- 導航選單、麵包屑、側邊欄區塊
- 資料摘要卡片、統計儀表板元件
- 第三方整合:社群分享按鈕、聊天插件、廣告區塊
- 表單複合欄位:日期選擇器、圖片上傳器、富文本編輯器