# Laravel 的視圖功能
- [創建視圖](#creating-views)
- [傳遞數據到視圖](#passing-data-to-views)
- [共享數據給所有視圖](#sharing-data-with-all-views)
- [視圖合成器](#view-composers)
<a name="creating-views"></a>
## 創建視圖
視圖包含你應用程序的HTML內容,并且能夠將你的控制器層邏輯(或應用層邏輯)與展現層邏輯分開。視圖文件存放于 `resources/views`目錄下 ,一個簡單的視圖示例如下:
<!-- 此視圖文件位置:resources/views/greeting.blade.php -->
<html>
<body>
<h1>Hello, {{ $name }}</h1>
</body>
</html>
該視圖文件位于 `resources/views/greeting.blade.php` ,我們可以通過全局函數 `view` 來使用這個它,比如:
Route::get('/', function () {
return view('greeting', ['name' => 'James']);
});
如你所見,`view` 函數中,傳入的第一個參數對應著 `resources/views` 目錄中視圖文件的文件名,第二個參數是一個數組,數組中的數據用于在視圖文件中使用。在示例中,我們將 `name` 變量傳遞到視圖中,并在視圖中使用 [Blade 模板語言](/docs/{{version}}/blade) 打印出來。
當然,視圖文件也嵌套在 `resources/views` 目錄的子目錄中,英文句點 `.` 可以用來引用嵌套的視圖。例如,一個位于 `resources/views/admin/profile.blade.php`的視圖 ,可以這樣引用它:
return view('admin.profile', $data);
#### 判斷一個視圖文件是否存在
如果需要判斷一個視圖文件是否存在,你可以使用 `View` Facade 上的 `exists` 方法來判定,如果視圖文件存在,該方法會返回 `true` :
use Illuminate\Support\Facades\View;
if (View::exists('emails.customer')) {
//
}
<a name="passing-data-to-views"></a>
## 傳遞數據至視圖
如上述例子所示,你可以使用數組將數據傳遞到視圖:
return view('greetings', ['name' => 'Victoria']);
當用這種方式傳遞數據時,第二個參數( `$data` )必須是鍵\值對數組。在視圖文件中,你可以通過對應的關鍵字( `$key` )取用相應的數據值,例如 `<?php echo $key; ?>`。如果只需要傳遞單個數據片段而非整個數組到視圖,您可以使用 `with` 方法:
return view('greeting')->with('name', 'Victoria');
<a name="sharing-data-with-all-views"></a>
#### 把數據共享給所有視圖
有時,您可能需要共享一段數據給應用程序的所有視圖,您可以使用`View` Facade 的 `share` 方法。通常需要將所有 `share` 方法的調用代碼放到 [服務提供者](/docs/{{version}}/providers) 的 `boot` 方法中,此時你可以選擇使用 `AppServiceProvider` 或創建獨立的 [服務提供者](/docs/{{version}}/providers) 。示例代碼如下:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
class AppServiceProvider extends ServiceProvider
{
/**
* 啟動任意應用服務
*
* @return void
*/
public function boot()
{
View::share('key', 'value');
}
/**
* 注冊服務提供者
*
* @return void
*/
public function register()
{
//
}
}
<a name="view-composers"></a>
## 視圖合成器
視圖合成器是在一個視圖被渲染時調用的一些回調或者類方法。如果你需要在某些視圖被渲染時綁定一些數據上去,那么視圖合成器就是你的的不二之選,另外他還可以幫你將這些綁定邏輯整理到特定的位置。
在下面這個例子中,我們會在一個 [服務提供者](/docs/{{version}}/providers) 中注冊一些視圖合成器。同時使用 `View` Facade 來訪問 `Illuminate\Contracts\View\Factory` contract 的底層實現。注意:Laravel 沒有存放視圖合成器的默認目錄,但你可以根據自己的喜好來重新組織,例如:`App\Http\ViewComposers`。
<?php
namespace App\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* 在容器中注冊綁定
*
* @return void
*/
public function boot()
{
// 使用基于類的合成器...
View::composer(
'profile', 'App\Http\ViewComposers\ProfileComposer'
);
// 使用基于閉包的合成器...
View::composer('dashboard', function ($view) {
//
});
}
/**
* 注冊服務器提供者
*
* @return void
*/
public function register()
{
//
}
}
> {note} 注意,如果你創建了新的一個 [服務提供者](/docs/{{version}}/providers) 來存放你視圖合成器的注冊項,那么你需要將這個 [服務提供者](/docs/{{version}}/providers) 添加到配置文件 `config/app.php` 的 `providers` 數組中。
到此我們已經注冊了上面的視圖合成器,效果是每次 `profile` 視圖渲染時,都會執行 `ProfileComposer@compose` 方法。那么下面我們來定義這個合成器類吧。
<?php
namespace App\Http\ViewComposers;
use Illuminate\View\View;
use App\Repositories\UserRepository;
class ProfileComposer
{
/**
* 實現用戶倉庫
*
* @var UserRepository
*/
protected $users;
/**
* 創建一個新的配置文件合成器
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
// 依賴關系由服務容器自動解析...
$this->users = $users;
}
/**
* 將數據綁定到視圖。
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view->with('count', $this->users->count());
}
}
每當視圖渲染時,該合成器的 `compose` 方法都會被調用,并且傳入一個 `Illuminate\View\View` 實例作為參數,在這個過程中,你可以使用 `with` 方法綁定數據到目標視圖。
> {tip} 所有的視圖合成器都會由 [服務容器](/docs/{{version}}/container) 來解析,所以你可以在合成器的構造函數中使用類型提示來注入需要的任何依賴。
#### 將視圖合成器附加到多個視圖
通過將目標視圖文件數組作為第一個參數傳入 `composer` 方法,你可以把一個視圖合成器同時附加到多個視圖。
View::composer(
['profile', 'dashboard'],
'App\Http\ViewComposers\MyViewComposer'
);
`composer` 方法同時也接受通配符 `*` ,可以讓你將一個視圖合成器一次性綁定到所有的視圖:
View::composer('*', function ($view) {
//
});
#### 視圖構造器
視圖 **構造器** 和視圖合成器非常相似。不同之處在于:視圖構造器在視圖實例化時執行,而視圖合成器在視圖渲染時執行。要注冊一個視圖塑造器,可以使用 `creator`方法,如下:
View::creator('profile', 'App\Http\ViewCreators\ProfileCreator');
---
> {note} 歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動共創開源社區。
>
> 轉載請注明:本文檔由 Laravel China 社區 [laravel-china.org](https://laravel-china.org) 組織翻譯,詳見 [翻譯召集帖](https://laravel-china.org/topics/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
>
> 文檔永久地址: https://d.laravel-china.org
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- HomeStead
- Valet
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- 門面(Facades)
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 重定向
- Session
- 表單驗證
- 錯誤與日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- API認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 交流說明